diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala index 0b033cf065..6974fad223 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala @@ -9,12 +9,25 @@ import org.bigbluebutton.common2.domain.DefaultProps body: CreateMeetingReqMsgBody) extends BbbCoreMsg case class CreateMeetingReqMsgBody(props: DefaultProps) + object DestroyMeetingSysCmdMsg { val NAME = "DestroyMeetingSysCmdMsg" } + case class DestroyMeetingSysCmdMsg(header: BbbCoreBaseHeader, + body: DestroyMeetingSysCmdMsgBody) extends BbbCoreMsg + case class DestroyMeetingSysCmdMsgBody(meetingId: String) + + object EndMeetingSysCmdMsg { val NAME = "DestroyMeetingReqMsg" } + case class EndMeetingSysCmdMsg(header: BbbCoreBaseHeader, + body: EndMeetingSysCmdMsgBody) extends BbbCoreMsg + case class EndMeetingSysCmdMsgBody(meetingId: String) object GetAllMeetingsReqMsg { val NAME = "GetAllMeetingsReqMsg" } case class GetAllMeetingsReqMsg(header: BbbCoreBaseHeader, body: GetAllMeetingsReqMsgBody) extends BbbCoreMsg case class GetAllMeetingsReqMsgBody(requesterId: String) + object PubSubPingSysReqMsg { val NAME = "PubSubPingSysReqMsg" } + case class PubSubPingSysReqMsg(header: BbbCoreBaseHeader, + body: PubSubPingSysReqMsgBody) extends BbbCoreMsg + case class PubSubPingSysReqMsgBody(system: String, timestamp: Long) /** Response Messages **/ object MeetingCreatedEvtMsg { val NAME = "MeetingCreatedEvtMsg"} @@ -22,12 +35,27 @@ import org.bigbluebutton.common2.domain.DefaultProps body: MeetingCreatedEvtBody) extends BbbCoreMsg case class MeetingCreatedEvtBody(props: DefaultProps) + object MeetingEndedEvtMsg { val NAME = "MeetingEndedEvtMsg"} + case class MeetingEndedEvtMsg(header: BbbCoreBaseHeader, + body: MeetingEndedEvtMsgBody) extends BbbCoreMsg + case class MeetingEndedEvtMsgBody(meetingId: String) - object SyncGetMeetingInfoRespMsg { val NAME = "SyncGetMeetingInfoRespMsg"} + object MeetingDestroyedEvtMsg { val NAME = "MeetingDestroyedEvtMsg"} + case class MeetingDestroyedEvtMsg(header: BbbCoreBaseHeader, + body: MeetingDestroyedEvtMsgBody) extends BbbCoreMsg + case class MeetingDestroyedEvtMsgBody(meetingId: String) + + + +object SyncGetMeetingInfoRespMsg { val NAME = "SyncGetMeetingInfoRespMsg"} case class SyncGetMeetingInfoRespMsg(header: BbbCoreBaseHeader, body: SyncGetMeetingInfoRespMsgBody) extends BbbCoreMsg case class SyncGetMeetingInfoRespMsgBody(props: DefaultProps) + object PubSubPongSysRespMsg { val NAME = "PubSubPongSysRespMsg" } + case class PubSubPongSysRespMsg(header: BbbCoreBaseHeader, + body: PubSubPongSysRespMsgBody) extends BbbCoreMsg + case class PubSubPongSysRespMsgBody(system: String, timestamp: Long) /** System Messages **/ case class AkkaAppsCheckAliveReqBody(timestamp: Long) diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/IReceivedOldMessageHandler.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/IReceivedOldMessageHandler.java index 10c99a8683..3123e0d959 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/IReceivedOldMessageHandler.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/IReceivedOldMessageHandler.java @@ -1,5 +1,7 @@ package org.bigbluebutton.api; +import org.bigbluebutton.api.messaging.messages.IMessage; + public interface IReceivedOldMessageHandler { - void handleMessage(String pattern, String channel, String message); + void handleMessage(IMessage msg); } 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 b531f72370..8a6baccdfe 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 @@ -1,20 +1,19 @@ /** * 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 . - * */ package org.bigbluebutton.api; @@ -42,6 +41,9 @@ import org.bigbluebutton.api.domain.*; import org.bigbluebutton.api.messaging.MessageListener; import org.bigbluebutton.api.messaging.MessagingConstants; import org.bigbluebutton.api.messaging.MessagingService; +import org.bigbluebutton.api.messaging.RedisStorageService; +import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage; +import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage; import org.bigbluebutton.api.messaging.messages.CreateBreakoutRoom; import org.bigbluebutton.api.messaging.messages.CreateMeeting; import org.bigbluebutton.api.messaging.messages.EndBreakoutRoom; @@ -62,6 +64,8 @@ import org.bigbluebutton.api.messaging.messages.UserStatusChanged; import org.bigbluebutton.api.messaging.messages.UserUnsharedWebcam; import org.bigbluebutton.api.pub.IPublisherService; 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; @@ -74,877 +78,884 @@ import org.slf4j.LoggerFactory; import com.google.gson.Gson; public class MeetingService implements MessageListener { - private static Logger log = LoggerFactory.getLogger(MeetingService.class); + private static Logger log = LoggerFactory.getLogger(MeetingService.class); - private BlockingQueue receivedMessages = new LinkedBlockingQueue(); - private volatile boolean processMessage = false; + private BlockingQueue receivedMessages = new LinkedBlockingQueue(); + private volatile boolean processMessage = false; - private final Executor msgProcessorExec = Executors - .newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); + private final Executor msgProcessorExec = Executors.newSingleThreadExecutor(); + private final Executor runExec = Executors.newSingleThreadExecutor(); - /** - * http://ria101.wordpress.com/2011/12/12/concurrenthashmap-avoid-a-common- - * misuse/ - */ - private final ConcurrentMap meetings; - private final ConcurrentMap sessions; + /** + * http://ria101.wordpress.com/2011/12/12/concurrenthashmap-avoid-a-common-misuse/ + */ + private final ConcurrentMap meetings; + private final ConcurrentMap sessions; - private RecordingService recordingService; - private MessagingService messagingService; - private RegisteredUserCleanupTimerTask registeredUserCleaner; - private StunTurnService stunTurnService; + private RecordingService recordingService; + private RegisteredUserCleanupTimerTask registeredUserCleaner; + private StunTurnService stunTurnService; + private RedisStorageService storeService; - private ParamsProcessorUtil paramsProcessorUtil; - private PresentationUrlDownloadService presDownloadService; + private ParamsProcessorUtil paramsProcessorUtil; + private PresentationUrlDownloadService presDownloadService; - private IBbbWebApiGWApp gw; + private IBbbWebApiGWApp gw; - public MeetingService() { - meetings = new ConcurrentHashMap(8, 0.9f, 1); - sessions = new ConcurrentHashMap(8, 0.9f, 1); + public MeetingService() { + meetings = new ConcurrentHashMap(8, 0.9f, 1); + sessions = new ConcurrentHashMap(8, 0.9f, 1); + } + + public void addUserSession(String token, UserSession user) { + sessions.put(token, user); + } + + public void registerUser(String meetingID, String internalUserId, + String fullname, String role, String externUserID, + String authToken, String avatarURL, Boolean guest, Boolean authed) { + handle(new RegisterUser(meetingID, internalUserId, fullname, role, + externUserID, authToken, avatarURL, guest, authed)); + } + + public UserSession getUserSession(String token) { + return sessions.get(token); + } + + public UserSession removeUserSession(String token) { + UserSession user = sessions.remove(token); + if (user != null) { + log.debug("Found user [" + user.fullname + "] token=[" + token + + "] to meeting [" + user.meetingID + "]"); } + return user; + } - public void addUserSession(String token, UserSession user) { - sessions.put(token, user); - } + /** + * Remove registered users who did not successfully joined the meeting. + */ + public void purgeRegisteredUsers() { + for (AbstractMap.Entry entry : this.meetings.entrySet()) { + Long now = System.nanoTime(); + Meeting meeting = entry.getValue(); - public void registerUser(String meetingID, String internalUserId, - String fullname, String role, String externUserID, - String authToken, String avatarURL, Boolean guest, Boolean authed) { - handle(new RegisterUser(meetingID, internalUserId, fullname, role, - externUserID, authToken, avatarURL, guest, authed)); - } + ConcurrentMap users = meeting.getUsersMap(); - public UserSession getUserSession(String token) { - return sessions.get(token); - } + for (AbstractMap.Entry registeredUser : meeting.getRegisteredUsers().entrySet()) { + String registeredUserID = registeredUser.getKey(); + Long registeredUserDate = registeredUser.getValue(); - public UserSession removeUserSession(String token) { - UserSession user = sessions.remove(token); - if (user != null) { - log.debug("Found user [" + user.fullname + "] token=[" + token - + "] to meeting [" + user.meetingID + "]"); + long registrationTime = registeredUserDate.longValue(); + long elapsedTime = now - registrationTime; + if (elapsedTime >= 60000 + && !users.containsKey(registeredUserID)) { + meeting.userUnregistered(registeredUserID); } - return user; + } + } + } + + private void kickOffProcessingOfRecording(Meeting m) { + if (m.isRecord() && m.getNumUsers() == 0) { + Map logData = new HashMap(); + logData.put("meetingId", m.getInternalId()); + logData.put("externalMeetingId", m.getExternalId()); + logData.put("name", m.getName()); + logData.put("event", "kick_off_ingest_and_processing"); + logData.put("description", "Start processing of recording."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + + log.info("Initiate recording processing: data={}", logStr); + + processRecording(m.getInternalId()); + } + } + + private void processMeetingForRemoval(Meeting m) { + kickOffProcessingOfRecording(m); + destroyMeeting(m.getInternalId()); + meetings.remove(m.getInternalId()); + removeUserSessions(m.getInternalId()); + } + + private void removeUserSessions(String meetingId) { + Iterator> iterator = sessions.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + UserSession userSession = entry.getValue(); + + if (userSession.meetingID.equals(meetingId)) { + iterator.remove(); + } + } + } + + private void destroyMeeting(String meetingId) { + gw.destroyMeeting(new DestroyMeetingMessage(meetingId)); + } + + public Collection getMeetings() { + return meetings.isEmpty() ? Collections.emptySet() + : Collections.unmodifiableCollection(meetings.values()); + } + + public Collection getSessions() { + return sessions.isEmpty() ? Collections.emptySet() + : Collections.unmodifiableCollection(sessions.values()); + } + + public synchronized boolean createMeeting(Meeting m) { + String internalMeetingId = paramsProcessorUtil.convertToInternalMeetingId(m.getExternalId()); + Meeting existing = getNotEndedMeetingWithId(internalMeetingId); + if (existing == null) { + meetings.put(m.getInternalId(), m); + handle(new CreateMeeting(m)); + return true; } - /** - * Remove registered users who did not successfully joined the meeting. - */ - public void purgeRegisteredUsers() { - for (AbstractMap.Entry entry : this.meetings - .entrySet()) { - Long now = System.nanoTime(); - Meeting meeting = entry.getValue(); + return false; + } - ConcurrentMap users = meeting.getUsersMap(); - - for (AbstractMap.Entry registeredUser : meeting - .getRegisteredUsers().entrySet()) { - String registeredUserID = registeredUser.getKey(); - Long registeredUserDate = registeredUser.getValue(); - - long registrationTime = registeredUserDate.longValue(); - long elapsedTime = now - registrationTime; - if (elapsedTime >= 60000 - && !users.containsKey(registeredUserID)) { - meeting.userUnregistered(registeredUserID); - } - } - } + private void handleCreateMeeting(Meeting m) { + if (m.isBreakout()) { + Meeting parent = meetings.get(m.getParentMeetingId()); + parent.addBreakoutRoom(m.getExternalId()); + if (parent.isRecord()) { + storeService.addBreakoutRoom(parent.getInternalId(), m.getInternalId()); + } } - private void kickOffProcessingOfRecording(Meeting m) { - if (m.isRecord() && m.getNumUsers() == 0) { - Map logData = new HashMap(); - logData.put("meetingId", m.getInternalId()); - logData.put("externalMeetingId", m.getExternalId()); - logData.put("name", m.getName()); - logData.put("event", "kick_off_ingest_and_processing"); - logData.put("description", "Start processing of recording."); + if (m.isRecord()) { + Map metadata = new TreeMap(); + metadata.putAll(m.getMetadata()); + // 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()); - Gson gson = new Gson(); - String logStr = gson.toJson(logData); + storeService.recordMeetingInfo(m.getInternalId(), metadata); - log.info("Initiate recording processing: data={}", logStr); - - processRecording(m.getInternalId()); - } + if (m.isBreakout()) { + Map breakoutMetadata = new TreeMap(); + breakoutMetadata.put("meetingId", m.getExternalId()); + breakoutMetadata.put("sequence", m.getSequence().toString()); + breakoutMetadata.put("parentMeetingId", m.getParentMeetingId()); + storeService.recordBreakoutInfo(m.getInternalId(), breakoutMetadata); + } } - private void processMeetingForRemoval(Meeting m) { - kickOffProcessingOfRecording(m); - destroyMeeting(m.getInternalId()); - meetings.remove(m.getInternalId()); - removeUserSessions(m.getInternalId()); + Map logData = new HashMap(); + logData.put("meetingId", m.getInternalId()); + logData.put("externalMeetingId", m.getExternalId()); + if (m.isBreakout()) { + logData.put("sequence", m.getSequence()); + 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."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + + log.info("Create meeting: data={}", logStr); + + gw.createMeeting(m.getInternalId(), m.getExternalId(), + m.getParentMeetingId(), m.getName(), m.isRecord(), + m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), + m.getAllowStartStopRecording(), m.getWebcamsOnlyForModerator(), + m.getModeratorPassword(), m.getViewerPassword(), + m.getCreateTime(), formatPrettyDate(m.getCreateTime()), + m.isBreakout(), m.getSequence(), m.getMetadata(), m.getGuestPolicy(), m.getWelcomeMessageTemplate(), + m.getWelcomeMessage(), m.getModeratorOnlyMessage(), m.getDialNumber(), m.getMaxUsers()); + + } + + private String formatPrettyDate(Long timestamp) { + return new Date(timestamp).toString(); + } + + private void processCreateMeeting(CreateMeeting message) { + handleCreateMeeting(message.meeting); + } + + private void processRegisterUser(RegisterUser message) { + gw.registerUser(message.meetingID, + message.internalUserId, message.fullname, message.role, + message.externUserID, message.authToken, message.avatarURL, message.guest, message.authed); + + gw.registerUser(message.meetingID, + message.internalUserId, message.fullname, message.role, + message.externUserID, message.authToken, message.avatarURL, message.guest, message.authed); + } + + public Meeting getMeeting(String meetingId) { + if (meetingId == null) + return null; + for (String key : meetings.keySet()) { + if (key.startsWith(meetingId)) + return (Meeting) meetings.get(key); } - private void removeUserSessions(String meetingId) { - Iterator> iterator = sessions.entrySet() - .iterator(); - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - UserSession userSession = entry.getValue(); + return null; + } - if (userSession.meetingID.equals(meetingId)) { - iterator.remove(); - } - } + public Collection getMeetingsWithId(String meetingId) { + if (meetingId == null) + return Collections.emptySet(); + + Collection m = new HashSet(); + + for (String key : meetings.keySet()) { + if (key.startsWith(meetingId)) + m.add(meetings.get(key)); } - private void destroyMeeting(String meetingID) { - messagingService.destroyMeeting(meetingID); + return m; + } + + public Meeting getNotEndedMeetingWithId(String meetingId) { + if (meetingId == null) + return null; + for (String key : meetings.keySet()) { + if (key.startsWith(meetingId)) { + Meeting m = (Meeting) meetings.get(key); + if (!m.isForciblyEnded()) + return m; + } } - public Collection getMeetings() { - return meetings.isEmpty() ? Collections. emptySet() - : Collections.unmodifiableCollection(meetings.values()); - } + return null; + } - public Collection getSessions() { - return sessions.isEmpty() ? Collections. emptySet() - : Collections.unmodifiableCollection(sessions.values()); - } + public List getRecordingsMetadata(List idList, List states) { + List recsList = recordingService.getRecordingsMetadata(idList, states); + return recsList; + } - public synchronized boolean createMeeting(Meeting m) { - String internalMeetingId = paramsProcessorUtil.convertToInternalMeetingId(m.getExternalId()); - Meeting existing = getNotEndedMeetingWithId(internalMeetingId); - if (existing == null) { - meetings.put(m.getInternalId(), m); - handle(new CreateMeeting(m)); - return true; + + public Map getRecordings(List idList, List states) { + List recsList = recordingService.getRecordings(idList, states); + Map recs = reorderRecordings(recsList); + return recs; + } + + public List filterRecordingsByMetadata(List recsList, + Map metadataFilters) { + return recordingService.filterRecordingsByMetadata(recsList, metadataFilters); + } + + public Map filterRecordingsByMetadata(Map recordings, + Map metadataFilters) { + return recordingService.filterRecordingsByMetadata(recordings, metadataFilters); + } + + + public Map reorderRecordings(List olds) { + Map map = new HashMap(); + for (Recording r : olds) { + if (!map.containsKey(r.getId())) { + Map meta = r.getMetadata(); + String mid = meta.remove("meetingId"); + String name = meta.remove("meetingName"); + + r.setMeetingID(mid); + r.setName(name); + + List plays = new ArrayList(); + + if (r.getPlaybackFormat() != null) { + plays.add(new Playback(r.getPlaybackFormat(), r.getPlaybackLink(), + getDurationRecording(r.getPlaybackDuration(), r.getEndTime(), + r.getStartTime()), r.getPlaybackSize(), r.getProcessingTime(), r.getPlaybackExtensions())); } - return false; + r.setPlaybacks(plays); + + ArrayList downloads = new ArrayList(); + + if (r.getDownloadFormat() != null) { + downloads.add(new Download(r.getDownloadFormat(), r.getDownloadLink(), + r.getDownloadMd5(), r.getDownloadKey(), + r.getDownloadSize(), + getDurationRecording(r.getEndTime(), r.getStartTime()))); + } + r.setDownloads(downloads); + + map.put(r.getId(), r); + } else { + Recording rec = map.get(r.getId()); + if (r.getPlaybackFormat() != null) { + rec.getPlaybacks().add(new Playback(r.getPlaybackFormat(), r.getPlaybackLink(), + getDurationRecording(r.getPlaybackDuration(), r.getEndTime(), r.getStartTime()), + r.getPlaybackSize(), r.getProcessingTime(), r.getPlaybackExtensions())); + } + if (r.getDownloadFormat() != null) { + rec.getDownloads().add(new Download(r.getDownloadFormat(), r.getDownloadLink(), r.getDownloadMd5(), + r.getDownloadKey(), r.getDownloadSize(), getDurationRecording(r.getEndTime(), r.getStartTime()))); + } + } } - private void handleCreateMeeting(Meeting m) { - if (m.isBreakout()){ - Meeting parent = meetings.get(m.getParentMeetingId()); - parent.addBreakoutRoom(m.getExternalId()); - if (parent.isRecord()) { - messagingService.addBreakoutRoom(parent.getInternalId(), m.getInternalId()); - } - } + return map; + } - if (m.isRecord()) { - Map metadata = new TreeMap(); - metadata.putAll(m.getMetadata()); - // 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()); + private int getDurationRecording(String end, String start) { + return getDurationRecording("", end, start); + } - messagingService.recordMeetingInfo(m.getInternalId(), metadata); + private int getDurationRecording(String playbackDuration, String end, + String start) { + int duration; + try { + if (!playbackDuration.equals("")) { + duration = (int) Math + .ceil((Long.parseLong(playbackDuration)) / 60000.0); + } else { + duration = (int) Math.ceil((Long.parseLong(end) - Long + .parseLong(start)) / 60000.0); + } + } catch (Exception e) { + log.debug(e.getMessage()); + duration = 0; + } - if (m.isBreakout()) { - Map breakoutMetadata = new TreeMap(); - breakoutMetadata.put("meetingId", m.getExternalId()); - breakoutMetadata.put("sequence", m.getSequence().toString()); - breakoutMetadata.put("parentMeetingId", m.getParentMeetingId()); - messagingService.recordBreakoutInfo(m.getInternalId(), breakoutMetadata); - } - } + return duration; + } + + public boolean existsAnyRecording(List idList) { + return recordingService.existAnyRecording(idList); + } + + public void setPublishRecording(List idList, boolean publish) { + for (String id : idList) { + if (publish) { + recordingService.changeState(id, Recording.STATE_PUBLISHED); + } else { + recordingService.changeState(id, Recording.STATE_UNPUBLISHED); + } + } + } + + public void deleteRecordings(List idList) { + for (String id : idList) { + recordingService.changeState(id, Recording.STATE_DELETED); + } + } + + public void updateRecordings(List idList, Map metaParams) { + recordingService.updateMetaParams(idList, metaParams); + } + + public void processRecording(String meetingId) { + recordingService.startIngestAndProcessing(meetingId); + } + + public boolean isMeetingWithVoiceBridgeExist(String voiceBridge) { + /* + * Collection confs = meetings.values(); for (Meeting c : + * confs) { if (voiceBridge == c.getVoiceBridge()) { return true; } } + */ + return false; + } + + + public void endMeeting(String meetingId) { + handle(new EndMeeting(meetingId)); + } + + private void processCreateBreakoutRoom(CreateBreakoutRoom message) { + Meeting parentMeeting = getMeeting(message.parentMeetingId); + if (parentMeeting != null) { + + Map params = new HashMap(); + params.put("name", message.name); + 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); + params.put("duration", message.durationInMinutes.toString()); + params.put("record", message.record.toString()); + params.put("welcome", getMeeting(message.parentMeetingId).getWelcomeMessageTemplate()); + + Map parentMeetingMetadata = parentMeeting.getMetadata(); + + String metaPrefix = "meta_"; + for (String key : parentMeetingMetadata.keySet()) { + String metaName = metaPrefix + key; + // Inject metadata from parent meeting into the breakout room. + params.put(metaName, parentMeetingMetadata.get(key)); + } + + Meeting breakout = paramsProcessorUtil.processCreateParams(params); + + createMeeting(breakout); + + presDownloadService.extractPresentationPage(message.parentMeetingId, + message.sourcePresentationId, + message.sourcePresentationSlide, breakout.getInternalId()); + } else { + log.error( + "Failed to create breakout room {}.Reason: Parent meeting {} not found.", + message.meetingId, message.parentMeetingId); + } + } + + private void processEndBreakoutRoom(EndBreakoutRoom message) { + processEndMeeting(new EndMeeting(message.breakoutMeetingId)); + } + + private void processEndMeeting(EndMeeting message) { + gw.endMeeting(new EndMeetingMessage(message.meetingId)); + } + + private void processRemoveEndedMeeting(MeetingEnded message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + m.setForciblyEnded(true); + processRecording(m.getInternalId()); + destroyMeeting(m.getInternalId()); + meetings.remove(m.getInternalId()); + removeUserSessions(m.getInternalId()); + } + } + + public void addUserCustomData(String meetingId, String userID, + Map userCustomData) { + Meeting m = getMeeting(meetingId); + if (m != null) { + m.addUserCustomData(userID, userCustomData); + } + } + + private void meetingStarted(MeetingStarted message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + if (m.getStartTime() == 0) { + long now = System.currentTimeMillis(); + m.setStartTime(now); Map logData = new HashMap(); logData.put("meetingId", m.getInternalId()); logData.put("externalMeetingId", m.getExternalId()); - if (m.isBreakout()){ - logData.put("sequence", m.getSequence()); - logData.put("parentMeetingId", m.getParentMeetingId()); + if (m.isBreakout()) { + 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."); + logData.put("isBreakout", m.isBreakout()); + logData.put("event", "meeting_started"); + logData.put("description", "Meeting has started."); Gson gson = new Gson(); String logStr = gson.toJson(logData); - log.info("Create meeting: 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()); + logData.put("isBreakout", m.isBreakout()); + logData.put("event", "meeting_restarted"); + logData.put("description", "Meeting has restarted."); + Gson gson = new Gson(); + String logStr = gson.toJson(logData); - messagingService.createMeeting(m.getInternalId(), m.getExternalId(), - m.getParentMeetingId(), m.getName(), m.isRecord(), - m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), - m.getAllowStartStopRecording(), m.getWebcamsOnlyForModerator(), - m.getModeratorPassword(), m.getViewerPassword(), - m.getCreateTime(), formatPrettyDate(m.getCreateTime()), - m.isBreakout(), m.getSequence(), m.getMetadata(), m.getGuestPolicy()); - - gw.createMeeting(m.getInternalId(), m.getExternalId(), - m.getParentMeetingId(), m.getName(), m.isRecord(), - m.getTelVoice(), m.getDuration(), m.getAutoStartRecording(), - m.getAllowStartStopRecording(), m.getWebcamsOnlyForModerator(), - m.getModeratorPassword(), m.getViewerPassword(), - m.getCreateTime(), formatPrettyDate(m.getCreateTime()), - m.isBreakout(), m.getSequence(), m.getMetadata(), m.getGuestPolicy(), m.getWelcomeMessageTemplate(), - m.getWelcomeMessage(), m.getModeratorOnlyMessage(), m.getDialNumber(), m.getMaxUsers()); - + log.info("Meeting restarted: data={}", logStr); + } + return; } + } - private String formatPrettyDate(Long timestamp) { - return new Date(timestamp).toString(); + private void meetingDestroyed(MeetingDestroyed message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + long now = System.currentTimeMillis(); + m.setEndTime(now); + + Map logData = new HashMap(); + logData.put("meetingId", m.getInternalId()); + logData.put("externalMeetingId", m.getExternalId()); + logData.put("name", m.getName()); + logData.put("duration", m.getDuration()); + logData.put("record", m.isRecord()); + logData.put("event", "meeting_destroyed"); + logData.put("description", "Meeting has been destroyed."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + + log.info("Meeting destroyed: data={}", logStr); + + return; } + } - private void processCreateMeeting(CreateMeeting message) { - handleCreateMeeting(message.meeting); + private void meetingEnded(MeetingEnded message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + long now = System.currentTimeMillis(); + m.setEndTime(now); + + Map logData = new HashMap(); + logData.put("meetingId", m.getInternalId()); + logData.put("externalMeetingId", m.getExternalId()); + logData.put("name", m.getName()); + logData.put("duration", m.getDuration()); + logData.put("record", m.isRecord()); + logData.put("event", "meeting_destroyed"); + logData.put("description", "Meeting has been destroyed."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + + log.info("Meeting destroyed: data={}", logStr); + + processRemoveEndedMeeting(message); + + return; } + } - private void processRegisterUser(RegisterUser message) { - messagingService.registerUser(message.meetingID, - message.internalUserId, message.fullname, message.role, - message.externUserID, message.authToken, message.avatarURL, message.guest, message.authed); + private void userJoined(UserJoined message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + if (m.getNumUsers() == 0) { + // First user joins the meeting. Reset the end time to zero + // in case the meeting has been rejoined. + m.setEndTime(0); + } - gw.registerUser(message.meetingID, - message.internalUserId, message.fullname, message.role, - message.externUserID, message.authToken, message.avatarURL, message.guest, message.authed); + User user = new User(message.userId, message.externalUserId, + message.name, message.role, message.avatarURL, message.guest, message.waitingForAcceptance); + m.userJoined(user); + + Map logData = new HashMap(); + logData.put("meetingId", m.getInternalId()); + logData.put("externalMeetingId", m.getExternalId()); + logData.put("name", m.getName()); + logData.put("userId", message.userId); + logData.put("externalUserId", user.getExternalUserId()); + logData.put("username", user.getFullname()); + logData.put("role", user.getRole()); + logData.put("guest", user.isGuest()); + logData.put("waitingForAcceptance", user.isWaitingForAcceptance()); + logData.put("event", MessagingConstants.USER_JOINED_EVENT); + logData.put("description", "User joined the meeting."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + log.info("User joined meeting: data={}", logStr); + + return; } + return; + } - public Meeting getMeeting(String meetingId) { - if (meetingId == null) - return null; - for (String key : meetings.keySet()) { - if (key.startsWith(meetingId)) - return (Meeting) meetings.get(key); + private void userLeft(UserLeft message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.userLeft(message.userId); + if (user != null) { + + Map logData = new HashMap(); + logData.put("meetingId", m.getInternalId()); + logData.put("externalMeetingId", m.getExternalId()); + logData.put("name", m.getName()); + logData.put("userId", message.userId); + logData.put("externalUserId", user.getExternalUserId()); + logData.put("username", user.getFullname()); + logData.put("role", user.getRole()); + logData.put("guest", user.isGuest()); + logData.put("waitingForAcceptance", user.isWaitingForAcceptance()); + logData.put("event", MessagingConstants.USER_LEFT_EVENT); + logData.put("description", "User left the meeting."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + + log.info("User left meeting: data={}", logStr); + + if (m.getNumUsers() == 0) { + // Last user the meeting. Mark this as the time + // the meeting ended. + m.setEndTime(System.currentTimeMillis()); } - return null; - } - - public Collection getMeetingsWithId(String meetingId) { - if (meetingId == null) - return Collections. emptySet(); - - Collection m = new HashSet(); - - for (String key : meetings.keySet()) { - if (key.startsWith(meetingId)) - m.add(meetings.get(key)); - } - - return m; - } - - public Meeting getNotEndedMeetingWithId(String meetingId) { - if (meetingId == null) - return null; - for (String key : meetings.keySet()) { - if (key.startsWith(meetingId)) { - Meeting m = (Meeting) meetings.get(key); - if (!m.isForciblyEnded()) - return m; - } - } - - return null; - } - - public List getRecordingsMetadata(List idList, List states) { - List recsList = recordingService.getRecordingsMetadata(idList, states); - return recsList; - } - - - public Map getRecordings(List idList, List states) { - List recsList = recordingService.getRecordings(idList, states); - Map recs = reorderRecordings(recsList); - return recs; - } - - public List filterRecordingsByMetadata(List recsList, - Map metadataFilters) { - return recordingService.filterRecordingsByMetadata(recsList, metadataFilters); - } - - public Map filterRecordingsByMetadata(Map recordings, - Map metadataFilters) { - return recordingService.filterRecordingsByMetadata(recordings, metadataFilters); - } - - - - public Map reorderRecordings(List olds) { - Map map = new HashMap(); - for (Recording r : olds) { - if (!map.containsKey(r.getId())) { - Map meta = r.getMetadata(); - String mid = meta.remove("meetingId"); - String name = meta.remove("meetingName"); - - r.setMeetingID(mid); - r.setName(name); - - List plays = new ArrayList(); - - if (r.getPlaybackFormat() != null) { - plays.add(new Playback(r.getPlaybackFormat(), r.getPlaybackLink(), - getDurationRecording(r.getPlaybackDuration(), r.getEndTime(), - r.getStartTime()), r.getPlaybackSize(), r.getProcessingTime(), r.getPlaybackExtensions())); - } - - r.setPlaybacks(plays); - - ArrayList downloads = new ArrayList(); - - if (r.getDownloadFormat() != null) { - downloads.add(new Download(r.getDownloadFormat(), r.getDownloadLink(), - r.getDownloadMd5(), r.getDownloadKey(), - r.getDownloadSize(), - getDurationRecording(r.getEndTime(), r.getStartTime()))); - } - r.setDownloads(downloads); - - map.put(r.getId(), r); - } else { - Recording rec = map.get(r.getId()); - if (r.getPlaybackFormat() != null) { - rec.getPlaybacks().add(new Playback(r.getPlaybackFormat(), r.getPlaybackLink(), - getDurationRecording(r.getPlaybackDuration(), r.getEndTime(), r.getStartTime()), - r.getPlaybackSize(), r.getProcessingTime(), r.getPlaybackExtensions())); - } - if (r.getDownloadFormat() != null) { - rec.getDownloads().add(new Download(r.getDownloadFormat(), r.getDownloadLink(), r.getDownloadMd5(), - r.getDownloadKey(), r.getDownloadSize(), getDurationRecording(r.getEndTime(), r.getStartTime()))); - } - } - } - - return map; - } - - private int getDurationRecording(String end, String start) { - return getDurationRecording("", end, start); - } - - private int getDurationRecording(String playbackDuration, String end, - String start) { - int duration; - try { - if (!playbackDuration.equals("")) { - duration = (int) Math - .ceil((Long.parseLong(playbackDuration)) / 60000.0); - } else { - duration = (int) Math.ceil((Long.parseLong(end) - Long - .parseLong(start)) / 60000.0); - } - } catch (Exception e) { - log.debug(e.getMessage()); - duration = 0; - } - - return duration; - } - - public boolean existsAnyRecording(List idList) { - return recordingService.existAnyRecording(idList); - } - - public void setPublishRecording(List idList, boolean publish) { - for (String id : idList) { - if (publish) { - recordingService.changeState(id, Recording.STATE_PUBLISHED); - } else { - recordingService.changeState(id, Recording.STATE_UNPUBLISHED); - } - } - } - - public void deleteRecordings(List idList) { - for (String id : idList) { - recordingService.changeState(id, Recording.STATE_DELETED); - } - } - - public void updateRecordings(List idList, Map metaParams) { - recordingService.updateMetaParams(idList, metaParams); - } - - public void processRecording(String meetingId) { - recordingService.startIngestAndProcessing(meetingId); - } - - public boolean isMeetingWithVoiceBridgeExist(String voiceBridge) { - /* - * Collection confs = meetings.values(); for (Meeting c : - * confs) { if (voiceBridge == c.getVoiceBridge()) { return true; } } - */return false; - } - - public void send(String channel, String message) { - messagingService.send(channel, message); - } - - public void endMeeting(String meetingId) { - handle(new EndMeeting(meetingId)); - } - - private void processCreateBreakoutRoom(CreateBreakoutRoom message) { - Meeting parentMeeting = getMeeting(message.parentMeetingId); - if (parentMeeting != null) { - - Map params = new HashMap(); - params.put("name", message.name); - 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); - params.put("duration", message.durationInMinutes.toString()); - params.put("record", message.record.toString()); - params.put("welcome", getMeeting(message.parentMeetingId) - .getWelcomeMessageTemplate()); - - Map parentMeetingMetadata = parentMeeting - .getMetadata(); - - String metaPrefix = "meta_"; - for (String key : parentMeetingMetadata.keySet()) { - String metaName = metaPrefix + key; - // Inject metadata from parent meeting into the breakout room. - params.put(metaName, parentMeetingMetadata.get(key)); - } - - Meeting breakout = paramsProcessorUtil.processCreateParams(params); - - createMeeting(breakout); - - presDownloadService.extractPresentationPage(message.parentMeetingId, - message.sourcePresentationId, - message.sourcePresentationSlide, breakout.getInternalId()); + Long userRegistered = m.userUnregistered(message.userId); + if (userRegistered != null) { + log.info("User unregistered from meeting"); } else { - log.error( - "Failed to create breakout room {}.Reason: Parent meeting {} not found.", - message.meetingId, message.parentMeetingId); + log.info("User was not unregistered from meeting because it was not found"); } - } - private void processEndBreakoutRoom(EndBreakoutRoom message) { - processEndMeeting(new EndMeeting(message.breakoutMeetingId)); - } - - private void processEndMeeting(EndMeeting message) { - messagingService.endMeeting(message.meetingId); - } - - private void processRemoveEndedMeeting(MeetingEnded message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - m.setForciblyEnded(true); - processRecording(m.getInternalId()); - destroyMeeting(m.getInternalId()); - meetings.remove(m.getInternalId()); - removeUserSessions(m.getInternalId()); - } - } - - public void addUserCustomData(String meetingId, String userID, - Map userCustomData) { - Meeting m = getMeeting(meetingId); - if (m != null) { - m.addUserCustomData(userID, userCustomData); - } - } - - private void meetingStarted(MeetingStarted message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - if (m.getStartTime() == 0) { - long now = System.currentTimeMillis(); - m.setStartTime(now); - - 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()); - logData.put("isBreakout", m.isBreakout()); - logData.put("event", "meeting_started"); - logData.put("description", "Meeting has started."); - - Gson gson = new Gson(); - String logStr = gson.toJson(logData); - - 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()); - logData.put("isBreakout", m.isBreakout()); - logData.put("event", "meeting_restarted"); - logData.put("description", "Meeting has restarted."); - - Gson gson = new Gson(); - String logStr = gson.toJson(logData); - - log.info("Meeting restarted: data={}", logStr); - } - return; - } - } - - private void meetingDestroyed(MeetingDestroyed message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - long now = System.currentTimeMillis(); - m.setEndTime(now); - - Map logData = new HashMap(); - logData.put("meetingId", m.getInternalId()); - logData.put("externalMeetingId", m.getExternalId()); - logData.put("name", m.getName()); - logData.put("duration", m.getDuration()); - logData.put("record", m.isRecord()); - logData.put("event", "meeting_destroyed"); - logData.put("description", "Meeting has been destroyed."); - - Gson gson = new Gson(); - String logStr = gson.toJson(logData); - - log.info("Meeting destroyed: data={}", logStr); - - return; - } - } - - private void meetingEnded(MeetingEnded message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - long now = System.currentTimeMillis(); - m.setEndTime(now); - - Map logData = new HashMap(); - logData.put("meetingId", m.getInternalId()); - logData.put("externalMeetingId", m.getExternalId()); - logData.put("name", m.getName()); - logData.put("duration", m.getDuration()); - logData.put("record", m.isRecord()); - logData.put("event", "meeting_destroyed"); - logData.put("description", "Meeting has been destroyed."); - - Gson gson = new Gson(); - String logStr = gson.toJson(logData); - - log.info("Meeting destroyed: data={}", logStr); - - processRemoveEndedMeeting(message); - - return; - } - } - - private void userJoined(UserJoined message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - if (m.getNumUsers() == 0) { - // First user joins the meeting. Reset the end time to zero - // in case the meeting has been rejoined. - m.setEndTime(0); - } - - User user = new User(message.userId, message.externalUserId, - message.name, message.role, message.avatarURL, message.guest, message.waitingForAcceptance); - m.userJoined(user); - - Map logData = new HashMap(); - logData.put("meetingId", m.getInternalId()); - logData.put("externalMeetingId", m.getExternalId()); - logData.put("name", m.getName()); - logData.put("userId", message.userId); - logData.put("externalUserId", user.getExternalUserId()); - logData.put("username", user.getFullname()); - logData.put("role", user.getRole()); - logData.put("guest", user.isGuest()); - logData.put("waitingForAcceptance", user.isWaitingForAcceptance()); - logData.put("event", MessagingConstants.USER_JOINED_EVENT); - logData.put("description", "User joined the meeting."); - - Gson gson = new Gson(); - String logStr = gson.toJson(logData); - log.info("User joined meeting: data={}", logStr); - - return; - } return; + } + + return; + } + } + + private void updatedStatus(UserStatusChanged message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.getUserById(message.userId); + if (user != null) { + user.setStatus(message.status, message.value); + return; + } + return; + } + } + + @Override + public void handle(IMessage message) { + receivedMessages.add(message); + } + + public void setParamsProcessorUtil(ParamsProcessorUtil util) { + this.paramsProcessorUtil = util; + } + + public void setPresDownloadService( + PresentationUrlDownloadService presDownloadService) { + this.presDownloadService = presDownloadService; + } + + private void processStunTurnInfoRequested(StunTurnInfoRequested message) { + Set stuns = stunTurnService.getStunServers(); + log.info("\nhere are the stuns:"); + for (StunServer s : stuns) { + log.info("a stun: " + s.url); + } + Set turns = stunTurnService.getStunAndTurnServersFor(message.internalUserId); + + log.info("\nhere are the (" + turns.size() + ") turns for internalUserId:" + message.internalUserId); + for (TurnEntry t : turns) { + log.info("a org.bigbluebutton.web.services.turn: " + t.url + "username/pass=" + t.username + '/' + + t.password); } - private void userLeft(UserLeft message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.userLeft(message.userId); - if (user != null) { + ArrayList stunsArrayList = new ArrayList(); + Iterator stunsIter = stuns.iterator(); - Map logData = new HashMap(); - logData.put("meetingId", m.getInternalId()); - logData.put("externalMeetingId", m.getExternalId()); - logData.put("name", m.getName()); - logData.put("userId", message.userId); - logData.put("externalUserId", user.getExternalUserId()); - logData.put("username", user.getFullname()); - logData.put("role", user.getRole()); - logData.put("guest", user.isGuest()); - logData.put("waitingForAcceptance", user.isWaitingForAcceptance()); - logData.put("event", MessagingConstants.USER_LEFT_EVENT); - logData.put("description", "User left the meeting."); + while (stunsIter.hasNext()) { + StunServer aStun = (StunServer) stunsIter.next(); + if (aStun != null) { + stunsArrayList.add(aStun.url); + } + } - Gson gson = new Gson(); - String logStr = gson.toJson(logData); + ArrayList> turnsArrayList = new ArrayList>(); + Iterator turnsIter = turns.iterator(); + while (turnsIter.hasNext()) { + TurnEntry te = (TurnEntry) turnsIter.next(); + if (null != te) { + Map map = new HashMap(); + map.put(Constants.USERNAME, te.username); + map.put(Constants.URL, te.url); + map.put(Constants.TTL, te.ttl); + map.put(Constants.PASSWORD, te.password); - log.info("User left meeting: data={}", logStr); + turnsArrayList.add(map); + } + } - if (m.getNumUsers() == 0) { - // Last user the meeting. Mark this as the time - // the meeting ended. - m.setEndTime(System.currentTimeMillis()); - } + SendStunTurnInfoReplyMessage msg = new SendStunTurnInfoReplyMessage(message.meetingId, + message.internalUserId,stunsArrayList, turnsArrayList); + gw.sendStunTurnInfoReply(msg); + } - Long userRegistered = m.userUnregistered(message.userId); - if (userRegistered != null) { - log.info("User unregistered from meeting"); - } else { - log.info("User was not unregistered from meeting because it was not found"); - } + public void userJoinedVoice(UserJoinedVoice message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.getUserById(message.userId); + if (user != null) { + user.setVoiceJoined(true); + return; + } + return; + } + } - return; + public void userLeftVoice(UserLeftVoice message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.getUserById(message.userId); + if (user != null) { + user.setVoiceJoined(false); + return; + } + return; + } + } + + public void userListeningOnly(UserListeningOnly message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.getUserById(message.userId); + if (user != null) { + user.setListeningOnly(message.listenOnly); + return; + } + return; + } + } + + public void userSharedWebcam(UserSharedWebcam message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.getUserById(message.userId); + if (user != null) { + user.addStream(message.stream); + return; + } + return; + } + } + + public void userUnsharedWebcam(UserUnsharedWebcam message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.getUserById(message.userId); + if (user != null) { + user.removeStream(message.stream); + return; + } + return; + } + } + + private void userRoleChanged(UserRoleChanged message) { + Meeting m = getMeeting(message.meetingId); + if (m != null) { + User user = m.getUserById(message.userId); + if (user != null) { + user.setRole(message.role); + log.debug("Setting new role in meeting " + message.meetingId + " for participant:" + user.getFullname()); + return; + } + log.warn("The participant " + message.userId + " doesn't exist in the meeting " + message.meetingId); + return; + } + log.warn("The meeting " + message.meetingId + " doesn't exist"); + } + + private void processMessage(final IMessage message) { + Runnable task = new Runnable() { + public void run() { + if (message instanceof MeetingStarted) { + meetingStarted((MeetingStarted) message); + } else if (message instanceof MeetingDestroyed) { + meetingDestroyed((MeetingDestroyed) message); + } else if (message instanceof MeetingEnded) { + meetingEnded((MeetingEnded) message); + } else if (message instanceof UserJoined) { + userJoined((UserJoined) message); + } else if (message instanceof UserLeft) { + userLeft((UserLeft) message); + } else if (message instanceof UserStatusChanged) { + updatedStatus((UserStatusChanged) message); + } else if (message instanceof UserRoleChanged) { + userRoleChanged((UserRoleChanged) message); + } else if (message instanceof UserJoinedVoice) { + userJoinedVoice((UserJoinedVoice) message); + } else if (message instanceof UserLeftVoice) { + userLeftVoice((UserLeftVoice) message); + } else if (message instanceof UserListeningOnly) { + userListeningOnly((UserListeningOnly) message); + } else if (message instanceof UserSharedWebcam) { + userSharedWebcam((UserSharedWebcam) message); + } else if (message instanceof UserUnsharedWebcam) { + userUnsharedWebcam((UserUnsharedWebcam) message); + } else if (message instanceof CreateMeeting) { + processCreateMeeting((CreateMeeting) message); + } else if (message instanceof EndMeeting) { + processEndMeeting((EndMeeting) message); + } else if (message instanceof RegisterUser) { + processRegisterUser((RegisterUser) message); + } else if (message instanceof StunTurnInfoRequested) { + processStunTurnInfoRequested((StunTurnInfoRequested) message); + } else if (message instanceof CreateBreakoutRoom) { + processCreateBreakoutRoom((CreateBreakoutRoom) message); + } else if (message instanceof EndBreakoutRoom) { + processEndBreakoutRoom((EndBreakoutRoom) message); + } + } + }; + + runExec.execute(task); + } + + public void start() { + log.info("Starting Meeting Service."); + try { + processMessage = true; + Runnable messageReceiver = new Runnable() { + public void run() { + while (processMessage) { + try { + IMessage msg = receivedMessages.take(); + processMessage(msg); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (Exception e) { + log.error("Handling unexpected exception [{}]", + e.toString()); } - - return; + } } + }; + + msgProcessorExec.execute(messageReceiver); + } catch (Exception e) { + log.error("Error PRocessing Message"); } + } - private void updatedStatus(UserStatusChanged message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.getUserById(message.userId); - if (user != null) { - user.setStatus(message.status, message.value); - return; - } - return; - } - } + public void stop() { + processMessage = false; + registeredUserCleaner.stop(); + } - @Override - public void handle(IMessage message) { - receivedMessages.add(message); - } + public void setRecordingService(RecordingService s) { + recordingService = s; + } - public void setParamsProcessorUtil(ParamsProcessorUtil util) { - this.paramsProcessorUtil = util; - } + public void setRedisStorageService(RedisStorageService mess) { + storeService = mess; + } - public void setPresDownloadService( - PresentationUrlDownloadService presDownloadService) { - this.presDownloadService = presDownloadService; - } - - private void processStunTurnInfoRequested(StunTurnInfoRequested message) { - Set stuns = stunTurnService.getStunServers(); - log.info("\nhere are the stuns:"); - for (StunServer s : stuns) { - log.info("a stun: " + s.url); - } - Set turns = stunTurnService - .getStunAndTurnServersFor(message.internalUserId); - log.info("\nhere are the (" + turns.size() - + ") turns for internalUserId:" + message.internalUserId); - for (TurnEntry t : turns) { - log.info("a org.bigbluebutton.web.services.turn: " + t.url + "username/pass=" + t.username + '/' - + t.password); - } - messagingService.sendStunTurnInfo(message.meetingId, - message.internalUserId, stuns, turns); - } - - public void userJoinedVoice(UserJoinedVoice message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.getUserById(message.userId); - if (user != null) { - user.setVoiceJoined(true); - return; - } - return; - } - } - - public void userLeftVoice(UserLeftVoice message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.getUserById(message.userId); - if (user != null) { - user.setVoiceJoined(false); - return; - } - return; - } - } - - public void userListeningOnly(UserListeningOnly message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.getUserById(message.userId); - if (user != null) { - user.setListeningOnly(message.listenOnly); - return; - } - return; - } - } - - public void userSharedWebcam(UserSharedWebcam message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.getUserById(message.userId); - if (user != null) { - user.addStream(message.stream); - return; - } - return; - } - } - - public void userUnsharedWebcam(UserUnsharedWebcam message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.getUserById(message.userId); - if (user != null) { - user.removeStream(message.stream); - return; - } - return; - } - } - - private void userRoleChanged(UserRoleChanged message) { - Meeting m = getMeeting(message.meetingId); - if (m != null) { - User user = m.getUserById(message.userId); - if(user != null){ - user.setRole(message.role); - log.debug("Setting new role in meeting " + message.meetingId + " for participant:" + user.getFullname()); - return; - } - log.warn("The participant " + message.userId + " doesn't exist in the meeting " + message.meetingId); - return; - } - log.warn("The meeting " + message.meetingId + " doesn't exist"); - } - - private void processMessage(final IMessage message) { - Runnable task = new Runnable() { - public void run() { - if (message instanceof MeetingStarted) { - meetingStarted((MeetingStarted) message); - } else if (message instanceof MeetingDestroyed) { - meetingDestroyed((MeetingDestroyed) message); - } else if (message instanceof MeetingEnded) { - meetingEnded((MeetingEnded) message); - } else if (message instanceof UserJoined) { - userJoined((UserJoined) message); - } else if (message instanceof UserLeft) { - userLeft((UserLeft) message); - } else if (message instanceof UserStatusChanged) { - updatedStatus((UserStatusChanged) message); - } else if (message instanceof UserRoleChanged) { - userRoleChanged((UserRoleChanged)message); - } else if (message instanceof UserJoinedVoice) { - userJoinedVoice((UserJoinedVoice) message); - } else if (message instanceof UserLeftVoice) { - userLeftVoice((UserLeftVoice) message); - } else if (message instanceof UserListeningOnly) { - userListeningOnly((UserListeningOnly) message); - } else if (message instanceof UserSharedWebcam) { - userSharedWebcam((UserSharedWebcam) message); - } else if (message instanceof UserUnsharedWebcam) { - userUnsharedWebcam((UserUnsharedWebcam) message); - } else if (message instanceof CreateMeeting) { - processCreateMeeting((CreateMeeting) message); - } else if (message instanceof EndMeeting) { - processEndMeeting((EndMeeting) message); - } else if (message instanceof RegisterUser) { - processRegisterUser((RegisterUser) message); - } else if (message instanceof StunTurnInfoRequested) { - processStunTurnInfoRequested((StunTurnInfoRequested) message); - } else if (message instanceof CreateBreakoutRoom) { - processCreateBreakoutRoom((CreateBreakoutRoom) message); - } else if (message instanceof EndBreakoutRoom) { - processEndBreakoutRoom((EndBreakoutRoom) message); - } - } - }; - - runExec.execute(task); - } - - public void start() { - log.info("Starting Meeting Service."); - try { - processMessage = true; - Runnable messageReceiver = new Runnable() { - public void run() { - while (processMessage) { - try { - IMessage msg = receivedMessages.take(); - processMessage(msg); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (Exception e) { - log.error("Handling unexpected exception [{}]", - e.toString()); - } - } - } - }; - - msgProcessorExec.execute(messageReceiver); - } catch (Exception e) { - log.error("Error PRocessing Message"); - } - } - - public void stop() { - processMessage = false; - registeredUserCleaner.stop(); - } - - public void setRecordingService(RecordingService s) { - recordingService = s; - } - - public void setMessagingService(MessagingService mess) { - messagingService = mess; - } - - public void setGw(IBbbWebApiGWApp gw) { - this.gw = gw; - } + public void setGw(IBbbWebApiGWApp gw) { + this.gw = gw; + } - public void setRegisteredUserCleanupTimerTask( - RegisteredUserCleanupTimerTask c) { - registeredUserCleaner = c; - registeredUserCleaner.setMeetingService(this); - registeredUserCleaner.start(); - } + public void setRegisteredUserCleanupTimerTask( + RegisteredUserCleanupTimerTask c) { + registeredUserCleaner = c; + registeredUserCleaner.setMeetingService(this); + registeredUserCleaner.start(); + } - public void setStunTurnService(StunTurnService s) { - stunTurnService = s; - } + public void setStunTurnService(StunTurnService s) { + stunTurnService = s; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java index ace4445f26..5941c2927f 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MeetingMessageHandler.java @@ -42,167 +42,80 @@ public class MeetingMessageHandler implements MessageHandler { this.listeners = listeners; } - public void handleMessage(String pattern, String channel, String message) { - JsonParser parser = new JsonParser(); - JsonObject obj = (JsonObject) parser.parse(message); + public void handleMessage(IMessage message) { + /* + for (MessageListener listener : listeners) { + listener.handle(new MeetingStarted(meetingId)); + } + for (MessageListener listener : listeners) { + listener.handle(new MeetingEnded(meetingId)); + } + for (MessageListener listener : listeners) { + listener.handle(new MeetingDestroyed(meetingId)); + } + for (MessageListener listener : listeners) { + listener.handle(new CreateBreakoutRoom( + msg.payload.breakoutMeetingId, + msg.payload.parentMeetingId, + 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 + ) + ); + } + for (MessageListener listener : listeners) { + listener.handle(new EndBreakoutRoom(msg.payload.meetingId)); + } + IMessage rxMsg = null; + if (PubSubPongMessage.PUBSUB_PONG.equals(messageName)) { + IBigBlueButtonMessage msg = decoder.decodeMessage(message); + if (msg != null) { + PubSubPongMessage m = (PubSubPongMessage) msg; + rxMsg = new KeepAliveReply(m.payload.system, m.payload.timestamp); + } + } + if (rxMsg != null) { + for (MessageListener listener : listeners) { + listener.handle(rxMsg); + } + } + for (MessageListener listener : listeners) { + listener.handle(new UserJoined(meetingId, userid, externuserid, username, role, avatarURL, guest, waitingForAcceptance)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserStatusChanged(meetingId, userid, status, value)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserLeft(meetingId, userid)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserJoinedVoice(meetingId, userid)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserLeftVoice(meetingId, userid)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserListeningOnly(meetingId, userid, listenOnly)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserSharedWebcam(meetingId, userid, stream)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserUnsharedWebcam(meetingId, userid, stream)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserRoleChanged(meetingId, userid, role)); + } + for (MessageListener listener : listeners) { + listener.handle(new StunTurnInfoRequested(meetingId, requesterId)); + } +*/ - if (channel.equalsIgnoreCase(MessagingConstants.FROM_MEETING_CHANNEL)) { - if (obj.has("header") && obj.has("payload")) { - JsonObject header = (JsonObject) obj.get("header"); - JsonObject payload = (JsonObject) obj.get("payload"); - - if (header.has("name")) { - String messageName = header.get("name").getAsString(); - if(MessagingConstants.MEETING_STARTED_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new MeetingStarted(meetingId)); - } - } else if(MessagingConstants.MEETING_ENDED_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new MeetingEnded(meetingId)); - } - } else if (MessagingConstants.MEETING_DESTROYED_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - log.info("Received a meeting destroyed message for meeting id=[{}]", meetingId); - for (MessageListener listener : listeners) { - listener.handle(new MeetingDestroyed(meetingId)); - } - } else if (CreateBreakoutRoomRequest.NAME.equals(messageName)) { - CreateBreakoutRoomRequest msg = new Gson().fromJson(message, CreateBreakoutRoomRequest.class); - for (MessageListener listener : listeners) { - listener.handle(new CreateBreakoutRoom( - msg.payload.breakoutMeetingId, - msg.payload.parentMeetingId, - 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 - ) - ); - } - } - else if (EndBreakoutRoomRequest.NAME.equals(messageName)) { - EndBreakoutRoomRequest msg = new Gson().fromJson(message, EndBreakoutRoomRequest.class); - 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)); - } - } - } - } - } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_SYSTEM_CHANNEL)) { - if (obj.has("header") && obj.has("payload")) { - JsonObject header = (JsonObject) obj.get("header"); - JsonObject payload = (JsonObject) obj.get("payload"); - if (header.has("name")) { - String messageName = header.get("name").getAsString(); - IMessage rxMsg = null; - if (PubSubPongMessage.PUBSUB_PONG.equals(messageName)) { - IBigBlueButtonMessage msg = decoder.decodeMessage(message); - if (msg != null) { - PubSubPongMessage m = (PubSubPongMessage) msg; - rxMsg = new KeepAliveReply(m.payload.system, m.payload.timestamp); - } - } - if (rxMsg != null) { - for (MessageListener listener : listeners) { - listener.handle(rxMsg); - } - } - } - } - } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_USERS_CHANNEL)) { - if (obj.has("header") && obj.has("payload")) { - JsonObject header = (JsonObject) obj.get("header"); - JsonObject payload = (JsonObject) obj.get("payload"); - if (header.has("name")) { - String messageName = header.get("name").getAsString(); - if (MessagingConstants.USER_JOINED_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - JsonObject user = (JsonObject) payload.get("user"); - String userid = user.get("userid").getAsString(); - String externuserid = user.get("extern_userid").getAsString(); - String username = user.get("name").getAsString(); - String role = user.get("role").getAsString(); - String avatarURL = user.get("avatarURL").getAsString(); - Boolean guest = user.get("guest").getAsBoolean(); - Boolean waitingForAcceptance = user.get("waiting_for_acceptance").getAsBoolean(); - for (MessageListener listener : listeners) { - listener.handle(new UserJoined(meetingId, userid, externuserid, username, role, avatarURL, guest, waitingForAcceptance)); - } - } else if(MessagingConstants.USER_STATUS_CHANGE_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - String userid = payload.get("userid").getAsString(); - String status = payload.get("status").getAsString(); - String value = payload.get("value").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new UserStatusChanged(meetingId, userid, status, value)); - } - } else if (MessagingConstants.USER_LEFT_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - JsonObject user = (JsonObject) payload.get("user"); - String userid = user.get("userid").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new UserLeft(meetingId, userid)); - } - } else if (MessagingConstants.USER_JOINED_VOICE_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - JsonObject user = (JsonObject) payload.get("user"); - String userid = user.get("userid").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new UserJoinedVoice(meetingId, userid)); - } - } else if (MessagingConstants.USER_LEFT_VOICE_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - JsonObject user = (JsonObject) payload.get("user"); - String userid = user.get("userid").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new UserLeftVoice(meetingId, userid)); - } - } else if (MessagingConstants.USER_LISTEN_ONLY_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - String userid = payload.get("userid").getAsString(); - Boolean listenOnly = payload.get("listen_only").getAsBoolean(); - for (MessageListener listener : listeners) { - listener.handle(new UserListeningOnly(meetingId, userid, listenOnly)); - } - } else if (MessagingConstants.USER_SHARE_WEBCAM_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - String userid = payload.get("userid").getAsString(); - String stream = payload.get("stream").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new UserSharedWebcam(meetingId, userid, stream)); - } - } else if (MessagingConstants.USER_UNSHARE_WEBCAM_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - String userid = payload.get("userid").getAsString(); - String stream = payload.get("stream").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new UserUnsharedWebcam(meetingId, userid, stream)); - } - } else if (MessagingConstants.USER_ROLE_CHANGE_EVENT.equalsIgnoreCase(messageName)) { - String meetingId = payload.get("meeting_id").getAsString(); - String userid = payload.get("userid").getAsString(); - String role = payload.get("role").getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new UserRoleChanged(meetingId, userid, role)); - } - } else if (SendStunTurnInfoRequestMessage.SEND_STUN_TURN_INFO_REQUEST_MESSAGE.equalsIgnoreCase(messageName)) { - String meetingId = payload.get(Constants.MEETING_ID).getAsString(); - String requesterId = payload.get(Constants.REQUESTER_ID).getAsString(); - for (MessageListener listener : listeners) { - listener.handle(new StunTurnInfoRequested(meetingId, requesterId)); - } - } - } - } - } } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java index d8cd308c9d..b6bd5e086f 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageDistributor.java @@ -1,25 +1,27 @@ package org.bigbluebutton.api.messaging; +import org.bigbluebutton.api.messaging.messages.IMessage; + import java.util.Set; public class MessageDistributor { - private ReceivedMessageHandler handler; - private Set listeners; - - public void setMessageListeners(Set listeners) { - this.listeners = listeners; - } - - public void setMessageHandler(ReceivedMessageHandler handler) { - this.handler = handler; - if (handler != null) { - handler.setMessageDistributor(this); - } - } - - public void notifyListeners(String pattern, String channel, String message) { - for (MessageHandler listener : listeners) { - listener.handleMessage(pattern, channel, message); - } - } + private ReceivedMessageHandler handler; + private Set listeners; + + public void setMessageListeners(Set listeners) { + this.listeners = listeners; + } + + public void setMessageHandler(ReceivedMessageHandler handler) { + this.handler = handler; + if (handler != null) { + handler.setMessageDistributor(this); + } + } + + public void notifyListeners(IMessage message) { + for (MessageListener listener : listeners) { + listener.handle(message); + } + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageHandler.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageHandler.java index a6fe30d289..0ccb8c2669 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageHandler.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageHandler.java @@ -1,23 +1,24 @@ /** -* 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 . -* -*/ + * 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 . + */ package org.bigbluebutton.api.messaging; +import org.bigbluebutton.api.messaging.messages.IMessage; + public interface MessageHandler { - void handleMessage(String pattern, String channel, String message); + void handleMessage(IMessage message); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageListener.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageListener.java index 4779ea975b..0217a1336c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageListener.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageListener.java @@ -1,26 +1,25 @@ /** -* 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 . -* -*/ + * 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 . + */ package org.bigbluebutton.api.messaging; import org.bigbluebutton.api.messaging.messages.IMessage; public interface MessageListener { - void handle(IMessage message); + void handle(IMessage message); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageReceiver.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageReceiver.java deleted file mode 100755 index 4ce0fdb611..0000000000 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessageReceiver.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.bigbluebutton.api.messaging; - -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPubSub; -import redis.clients.jedis.exceptions.JedisConnectionException; - -public class MessageReceiver { - private static Logger log = LoggerFactory.getLogger(MessageReceiver.class); - - private ReceivedMessageHandler handler; - - private Jedis jedis; - private volatile boolean receiveMessage = false; - - private final Executor msgReceiverExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - - private String host; - private int port; - - public void stop() { - receiveMessage = false; - } - - public void start() { - log.info("Ready to receive messages from Redis pubsub."); - try { - receiveMessage = true; - jedis = new Jedis(host, port); - // Set the name of this client to be able to distinguish when doing - // CLIENT LIST on redis-cli - jedis.clientSetname("BbbWebSub"); - - Runnable messageReceiver = new Runnable() { - public void run() { - if (receiveMessage) { - try { - jedis.psubscribe(new PubSubListener(), MessagingConstants.FROM_BBB_APPS_PATTERN); - } catch(JedisConnectionException ex) { - log.warn("Exception on Jedis connection. Resubscribing to pubsub."); - start(); - } catch (Exception e) { - log.error("Error resubscribing to channels: " + e.getMessage()); - } - } - } - }; - msgReceiverExec.execute(messageReceiver); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - public void setHost(String host){ - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setMessageHandler(ReceivedMessageHandler handler) { - this.handler = handler; - } - - private class PubSubListener extends JedisPubSub { - - public PubSubListener() { - super(); - } - - @Override - public void onMessage(String channel, String message) { - // Not used. - } - - @Override - public void onPMessage(final String pattern, final String channel, final String message) { - Runnable task = new Runnable() { - public void run() { - handler.handleMessage(pattern, channel, message); - } - }; - - runExec.execute(task); - } - - @Override - public void onPSubscribe(String pattern, int subscribedChannels) { - log.debug("Subscribed to the pattern: " + pattern); - } - - @Override - public void onPUnsubscribe(String pattern, int subscribedChannels) { - // Not used. - } - - @Override - public void onSubscribe(String channel, int subscribedChannels) { - // Not used. - } - - @Override - public void onUnsubscribe(String channel, int subscribedChannels) { - // Not used. - } - } -} - diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessagingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessagingService.java index 1671d594c0..27ef5d9c82 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessagingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/MessagingService.java @@ -1,49 +1,63 @@ /** -* 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 . -* -*/ + * 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 . + */ package org.bigbluebutton.api.messaging; +import org.bigbluebutton.presentation.messages.IDocConversionMsg; import org.bigbluebutton.web.services.turn.StunServer; import org.bigbluebutton.web.services.turn.TurnEntry; import java.util.Map; import java.util.Set; -public interface MessagingService { - void recordMeetingInfo(String meetingId, Map info); - void recordBreakoutInfo(String meetingId, Map breakoutInfo); - void addBreakoutRoom(String parentId, String breakoutId); - void send(String channel, String message); - void publishRecording(String recordId, String meetingId, String externalMeetingId, String format, boolean publish); - void deleteRecording(String recordId, String meetingId, String externalMeetingId, String format); - void createMeeting(String meetingID, String externalMeetingID, - String parentMeetingID, String meetingName, Boolean recorded, - String voiceBridge, Integer duration, Boolean autoStartRecording, - Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator, - String moderatorPass, String viewerPass, Long createTime, - String createDate, Boolean isBreakout, Integer sequence, - Map metadata, String guestPolicy); - void registerUser(String meetingID, String internalUserId, String fullname, String role, - String externUserID, String authToken, String avatarURL, Boolean guest, Boolean authed); - void destroyMeeting(String meetingID); - void endMeeting(String meetingId); - void sendKeepAlive(String system, Long timestamp); - void sendStunTurnInfo(String meetingId, String internalUserId, Set stuns, Set turns); +public interface MessagingService { + void recordMeetingInfo(String meetingId, Map info); + + void recordBreakoutInfo(String meetingId, Map breakoutInfo); + + void addBreakoutRoom(String parentId, String breakoutId); +/* + void send(String channel, String message); + + void publishRecording(String recordId, String meetingId, String externalMeetingId, String format, boolean publish); + + void deleteRecording(String recordId, String meetingId, String externalMeetingId, String format); + + void createMeeting(String meetingID, String externalMeetingID, + String parentMeetingID, String meetingName, Boolean recorded, + String voiceBridge, Integer duration, Boolean autoStartRecording, + Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator, + String moderatorPass, String viewerPass, Long createTime, + String createDate, Boolean isBreakout, Integer sequence, + Map metadata, String guestPolicy); + + void registerUser(String meetingID, String internalUserId, String fullname, String role, + String externUserID, String authToken, String avatarURL, Boolean guest, Boolean authed); + + void destroyMeeting(String meetingID); + + void endMeeting(String meetingId); + + void sendKeepAlive(String system, Long timestamp); + + void sendStunTurnInfo(String meetingId, String internalUserId, Set stuns, Set turns); + + void sendDocConversionMsg(IDocConversionMsg msg); + */ } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessage.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessage.java index 88e8b2cead..aa8bb39383 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessage.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessage.java @@ -1,25 +1,16 @@ package org.bigbluebutton.api.messaging; +import org.bigbluebutton.api.messaging.messages.IMessage; + public class ReceivedMessage { - private final String pattern; - private final String channel; - private final String message; - - public ReceivedMessage(String pattern, String channel, String message) { - this.pattern = pattern; - this.channel = channel; - this.message = message; - } + private final IMessage message; - public String getPattern() { - return pattern; - } + public ReceivedMessage(IMessage message) { - public String getChannel() { - return channel; - } + this.message = message; + } - public String getMessage() { - return message; - } + public IMessage getMessage() { + return message; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java index 63a3cefeae..831574bcfc 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/ReceivedMessageHandler.java @@ -1,76 +1,76 @@ package org.bigbluebutton.api.messaging; +import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; - import org.bigbluebutton.api.IReceivedOldMessageHandler; +import org.bigbluebutton.api.messaging.messages.IMessage; +import org.bigbluebutton.api2.bus.OldMessageReceivedGW; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ReceivedMessageHandler implements IReceivedOldMessageHandler { - private static Logger log = LoggerFactory.getLogger(ReceivedMessageHandler.class); - - private BlockingQueue receivedMessages = new LinkedBlockingQueue(); - - private volatile boolean processMessage = false; - - private final Executor msgProcessorExec = Executors.newSingleThreadExecutor(); - private final Executor runExec = Executors.newSingleThreadExecutor(); - - private MessageDistributor handler; - - public void stop() { - processMessage = false; - } - - public void start() { - log.info("Ready to handle messages from Redis pubsub!"); + private static Logger log = LoggerFactory.getLogger(ReceivedMessageHandler.class); - try { - processMessage = true; - - Runnable messageProcessor = new Runnable() { - public void run() { - while (processMessage) { - try { - ReceivedMessage msg = receivedMessages.take(); - processMessage(msg); - } catch (InterruptedException e) { - log.warn("Error while taking received message from queue."); - } - } - } - }; - msgProcessorExec.execute(messageProcessor); - } catch (Exception e) { - log.error("Error subscribing to channels: " + e.getMessage()); - } - } - - private void processMessage(final ReceivedMessage msg) { - Runnable task = new Runnable() { - public void run() { - if (handler != null) { -// log.debug("Let's process this message: " + msg.getMessage()); + private BlockingQueue receivedMessages = new LinkedBlockingQueue(); - handler.notifyListeners(msg.getPattern(), msg.getChannel(), msg.getMessage()); - } else { - log.warn("No listeners interested in messages from Redis!"); - } - } - }; - - runExec.execute(task); - } - - public void handleMessage(String pattern, String channel, String message) { - ReceivedMessage rm = new ReceivedMessage(pattern, channel, message); - receivedMessages.add(rm); - } - - public void setMessageDistributor(MessageDistributor h) { - this.handler = h; - } + private volatile boolean processMessage = false; + + private final Executor msgProcessorExec = Executors.newSingleThreadExecutor(); + private final Executor runExec = Executors.newSingleThreadExecutor(); + + private MessageDistributor outGW; + + public void stop() { + processMessage = false; + } + + public void start() { + log.info("Ready to handle messages from Redis pubsub!"); + + try { + processMessage = true; + + Runnable messageProcessor = new Runnable() { + public void run() { + while (processMessage) { + try { + ReceivedMessage msg = receivedMessages.take(); + processMessage(msg); + } catch (InterruptedException e) { + log.warn("Error while taking received message from queue."); + } + } + } + }; + msgProcessorExec.execute(messageProcessor); + } catch (Exception e) { + log.error("Error subscribing to channels: " + e.getMessage()); + } + } + + private void notifyListeners(IMessage message) { + outGW.notifyListeners(message); + } + + private void processMessage(final ReceivedMessage msg) { + Runnable task = new Runnable() { + public void run() { + notifyListeners(msg.getMessage()); + } + }; + + runExec.execute(task); + } + + public void handleMessage(IMessage message) { + ReceivedMessage rm = new ReceivedMessage(message); + receivedMessages.add(rm); + } + + public void setMessageDistributor(MessageDistributor outGW) { + this.outGW = outGW; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisMessagingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisMessagingService.java index ea7d02b357..25b3131aef 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisMessagingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisMessagingService.java @@ -1,21 +1,20 @@ /** -* 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 . -* -*/ + * 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 . + */ package org.bigbluebutton.api.messaging; @@ -31,6 +30,7 @@ import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage; import org.bigbluebutton.api.messaging.converters.messages.PublishRecordingMessage; import org.bigbluebutton.api.messaging.converters.messages.UnpublishRecordingMessage; +import org.bigbluebutton.api2.IBbbWebApiGWApp; import org.bigbluebutton.common.converters.ToJsonEncoder; import org.bigbluebutton.common.messages.Constants; import org.bigbluebutton.common.messages.MessagingConstants; @@ -39,6 +39,7 @@ import org.bigbluebutton.messages.CreateMeetingRequest; import org.bigbluebutton.messages.CreateMeetingRequestPayload; import org.bigbluebutton.messages.RegisterUserMessage; import org.bigbluebutton.messages.RegisterUserMessagePayload; +import org.bigbluebutton.presentation.messages.IDocConversionMsg; import org.bigbluebutton.web.services.turn.StunServer; import org.bigbluebutton.web.services.turn.TurnEntry; import org.slf4j.Logger; @@ -46,162 +47,113 @@ import org.slf4j.LoggerFactory; import com.google.gson.Gson; -public class RedisMessagingService implements MessagingService { - private static Logger log = LoggerFactory.getLogger(RedisMessagingService.class); - - private RedisStorageService storeService; - private MessageSender sender; - private ToJsonEncoder encoder = new ToJsonEncoder(); - - public void recordMeetingInfo(String meetingId, Map info) { - storeService.recordMeetingInfo(meetingId, info); - } +public class RedisMessagingService { + private static Logger log = LoggerFactory.getLogger(RedisMessagingService.class); - public void recordBreakoutInfo(String meetingId, Map breakoutInfo) { - storeService.recordBreakoutInfo(meetingId, breakoutInfo); - } - public void addBreakoutRoom(String parentId, String breakoutId) { - storeService.addBreakoutRoom(parentId, breakoutId); - } + public void destroyMeeting(String meetingID) { + DestroyMeetingMessage msg = new DestroyMeetingMessage(meetingID); - public void destroyMeeting(String meetingID) { - DestroyMeetingMessage msg = new DestroyMeetingMessage(meetingID); - String json = MessageToJson.destroyMeetingMessageToJson(msg); - log.info("Sending destroy meeting message to bbb-apps:[{}]", json); - sender.send(MessagingConstants.TO_MEETING_CHANNEL, json); - } - - public void registerUser(String meetingID, String internalUserId, String fullname, String role, - String externUserID, String authToken, String avatarURL, Boolean guest, Boolean authed) { - RegisterUserMessagePayload payload = new RegisterUserMessagePayload(meetingID, internalUserId, fullname, role, externUserID, - authToken, avatarURL, guest, authed); - RegisterUserMessage msg = new RegisterUserMessage(payload); + } - Gson gson = new Gson(); - String json = gson.toJson(msg); - log.info("*****Sending register user 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, Boolean webcamsOnlyForModerator, - String moderatorPass, String viewerPass, Long createTime, - String createDate, Boolean isBreakout, Integer sequence, Map metadata, - String guestPolicy) { - CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload( - meetingID, externalMeetingID, parentMeetingID, meetingName, - recorded, voiceBridge, duration, autoStartRecording, - allowStartStopRecording, webcamsOnlyForModerator, - moderatorPass, viewerPass, createTime, createDate, isBreakout, - sequence, metadata, guestPolicy); - CreateMeetingRequest msg = new CreateMeetingRequest(payload); + public void registerUser(String meetingID, String internalUserId, String fullname, String role, + String externUserID, String authToken, String avatarURL, Boolean guest, Boolean authed) { + RegisterUserMessagePayload payload = new RegisterUserMessagePayload(meetingID, internalUserId, fullname, role, externUserID, + authToken, avatarURL, guest, authed); + RegisterUserMessage msg = new RegisterUserMessage(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); - String json = MessageToJson.endMeetingMessageToJson(msg); - log.info("Sending end meeting message to bbb-apps:[{}]", json); - sender.send(MessagingConstants.TO_MEETING_CHANNEL, json); - } + Gson gson = new Gson(); + String json = gson.toJson(msg); + log.info("*****Sending register user message to bbb-apps:[{}]", json); + + } + + public void createMeeting(String meetingID, String externalMeetingID, + String parentMeetingID, String meetingName, Boolean recorded, + String voiceBridge, Integer duration, Boolean autoStartRecording, + Boolean allowStartStopRecording, Boolean webcamsOnlyForModerator, + String moderatorPass, String viewerPass, Long createTime, + String createDate, Boolean isBreakout, Integer sequence, Map metadata, + String guestPolicy) { + CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload( + meetingID, externalMeetingID, parentMeetingID, meetingName, + recorded, voiceBridge, duration, autoStartRecording, + allowStartStopRecording, webcamsOnlyForModerator, + moderatorPass, viewerPass, createTime, createDate, isBreakout, + sequence, metadata, guestPolicy); + CreateMeetingRequest msg = new CreateMeetingRequest(payload); + + Gson gson = new Gson(); + String json = gson.toJson(msg); + log.info("Sending create meeting message to bbb-apps:[{}]", json); + + } + + public void endMeeting(String meetingId) { + EndMeetingMessage msg = new EndMeetingMessage(meetingId); + String json = MessageToJson.endMeetingMessageToJson(msg); + log.info("Sending end meeting message to bbb-apps:[{}]", json); + + } public void sendKeepAlive(String system, Long timestamp) { - String json = encoder.encodePubSubPingMessage("BbbWeb", System.currentTimeMillis()); - sender.send(MessagingConstants.TO_SYSTEM_CHANNEL, json); + } - + public void send(String channel, String message) { - sender.send(channel, message); + } - - public void sendPolls(String meetingId, String title, String question, String questionType, List answers){ - Gson gson = new Gson(); - HashMap map = new HashMap(); - map.put("messageId", MessagingConstants.SEND_POLLS_EVENT); - map.put("meetingId", meetingId); - map.put("title", title); - map.put("question", question); - map.put("questionType", questionType); - map.put("answers", answers); - - sender.send(MessagingConstants.TO_POLLING_CHANNEL, gson.toJson(map)); - } - - public void setMessageSender(MessageSender sender) { - this.sender = sender; - } - - public void setRedisStorageService(RedisStorageService storeService) { - this.storeService = storeService; + public void sendPolls(String meetingId, String title, String question, String questionType, List answers) { + Gson gson = new Gson(); + + HashMap map = new HashMap(); + map.put("messageId", MessagingConstants.SEND_POLLS_EVENT); + map.put("meetingId", meetingId); + map.put("title", title); + map.put("question", question); + map.put("questionType", questionType); + map.put("answers", answers); + + } - - public void removeMeeting(String meetingId){ - storeService.removeMeeting(meetingId); - } - private void publishRecording(String recordId, String meetingId, String externalMeetingId, String format) { - PublishRecordingMessage msg = new PublishRecordingMessage(recordId, meetingId, externalMeetingId, format); - String json = MessageToJson.publishRecordingMessageToJson(msg); - sender.send(MessagingConstants.FROM_BBB_RECORDING_CHANNEL, json); - } - private void unpublishRecording(String recordId, String meetingId, String externalMeetingId, String format) { - UnpublishRecordingMessage msg = new UnpublishRecordingMessage(recordId, meetingId, externalMeetingId, format); - String json = MessageToJson.unpublishRecordingMessageToJson(msg); - sender.send(MessagingConstants.FROM_BBB_RECORDING_CHANNEL, json); - } + public void publishRecording(PublishRecordingMessage msg) { - public void publishRecording(String recordId, String meetingId, String externalMeetingId, String format, boolean publish) { - if (publish) { - publishRecording(recordId, meetingId, externalMeetingId, format); - } else { - unpublishRecording(recordId, meetingId, externalMeetingId, format); - } - } + String json = MessageToJson.publishRecordingMessageToJson(msg); - public void deleteRecording(String recordId, String meetingId, String externalMeetingId, String format) { - DeleteRecordingMessage msg = new DeleteRecordingMessage(recordId, meetingId, externalMeetingId, format); - String json = MessageToJson.deleteRecordingMessageToJson(msg); - sender.send(MessagingConstants.FROM_BBB_RECORDING_CHANNEL, json); - } + } - public void sendStunTurnInfo(String meetingId, String internalUserId, Set stuns, Set turns) { - ArrayList stunsArrayList = new ArrayList(); - Iterator stunsIter = stuns.iterator(); + public void unpublishRecording(UnpublishRecordingMessage msg) { - while (stunsIter.hasNext()) { - StunServer aStun = (StunServer) stunsIter.next(); - if (aStun != null) { - stunsArrayList.add(aStun.url); - } - } + String json = MessageToJson.unpublishRecordingMessageToJson(msg); - ArrayList> turnsArrayList = new ArrayList>(); - Iterator turnsIter = turns.iterator(); - while (turnsIter.hasNext()) { - TurnEntry te = (TurnEntry) turnsIter.next(); - if (null != te) { - Map map = new HashMap(); - map.put(Constants.USERNAME, te.username); - map.put(Constants.URL, te.url); - map.put(Constants.TTL, te.ttl); - map.put(Constants.PASSWORD, te.password); + } - turnsArrayList.add(map); - } - } + public void publishRecording(String recordId, String meetingId, String externalMeetingId, String format, boolean publish) { + if (publish) { + PublishRecordingMessage msg = new PublishRecordingMessage(recordId, meetingId, externalMeetingId, format); + publishRecording(msg); + } else { + UnpublishRecordingMessage msg = new UnpublishRecordingMessage(recordId, meetingId, externalMeetingId, format); + unpublishRecording(msg); + } + } - SendStunTurnInfoReplyMessage msg = new SendStunTurnInfoReplyMessage(meetingId, internalUserId, - stunsArrayList, turnsArrayList); + public void deleteRecording(String recordId, String meetingId, String externalMeetingId, String format) { + DeleteRecordingMessage msg = new DeleteRecordingMessage(recordId, meetingId, externalMeetingId, format); + String json = MessageToJson.deleteRecordingMessageToJson(msg); - sender.send(MessagingConstants.TO_BBB_HTML5_CHANNEL, msg.toJson()); - } + } + + public void sendStunTurnInfo(String meetingId, String internalUserId, Set stuns, Set turns) { + + + + } + + public void sendDocConversionMsg(IDocConversionMsg msg) { + + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisStorageService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisStorageService.java index 45c823b3ad..f5e0f029e1 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisStorageService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/RedisStorageService.java @@ -11,79 +11,79 @@ import redis.clients.jedis.JedisPool; import redis.clients.jedis.Protocol; public class RedisStorageService { - private static Logger log = LoggerFactory.getLogger(RedisStorageService.class); - - private JedisPool redisPool; - private String host; - private int port; - - public void stop() { + private static Logger log = LoggerFactory.getLogger(RedisStorageService.class); - } - - public void start() { - // Set the name of this client to be able to distinguish when doing - // 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)); - } + private JedisPool redisPool; + private String host; + private int port; - 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(); - } + public void stop() { + + } + + public void start() { + // Set the name of this client to be able to distinguish when doing + // 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)); + } + + 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(); } + } - public void recordBreakoutInfo(String meetingId, Map breakoutInfo) { - Jedis jedis = redisPool.getResource(); - try { - 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 recordBreakoutInfo(String meetingId, Map breakoutInfo) { + Jedis jedis = redisPool.getResource(); + try { + 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 addBreakoutRoom(String parentId, String breakoutId) { - Jedis jedis = redisPool.getResource(); - try { + public void addBreakoutRoom(String parentId, String breakoutId) { + Jedis jedis = redisPool.getResource(); + try { - log.debug("Saving breakout room for meeting {}", parentId); - jedis.sadd("meeting:breakout:rooms:" + parentId, breakoutId); - } catch (Exception e) { - log.warn("Cannot record the info meeting:" + parentId, e); - } finally { - jedis.close(); - } - } - - public void removeMeeting(String meetingId){ - Jedis jedis = redisPool.getResource(); - try { - jedis.del("meeting-" + meetingId); - jedis.srem("meetings", meetingId); - } finally { - jedis.close(); - } - } - - public void setHost(String host){ - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } + log.debug("Saving breakout room for meeting {}", parentId); + jedis.sadd("meeting:breakout:rooms:" + parentId, breakoutId); + } catch (Exception e) { + log.warn("Cannot record the info meeting:" + parentId, e); + } finally { + jedis.close(); + } + } + + public void removeMeeting(String meetingId) { + Jedis jedis = redisPool.getResource(); + try { + jedis.del("meeting-" + meetingId); + jedis.srem("meetings", meetingId); + } finally { + jedis.close(); + } + } + + public void setHost(String host) { + this.host = host; + } + + public void setPort(int port) { + this.port = port; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/DestroyMeetingMessage.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/DestroyMeetingMessage.java index 83f2ad58e7..dc11c0747b 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/DestroyMeetingMessage.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/DestroyMeetingMessage.java @@ -1,12 +1,12 @@ package org.bigbluebutton.api.messaging.converters.messages; public class DestroyMeetingMessage { - public static final String DESTROY_MEETING_REQUEST_EVENT = "destroy_meeting_request_event"; - public static final String VERSION = "0.0.1"; - - public final String meetingId; - - public DestroyMeetingMessage(String meetingId) { - this.meetingId = meetingId; - } + public static final String DESTROY_MEETING_REQUEST_EVENT = "destroy_meeting_request_event"; + public static final String VERSION = "0.0.1"; + + public final String meetingId; + + public DestroyMeetingMessage(String meetingId) { + this.meetingId = meetingId; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/EndMeetingMessage.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/EndMeetingMessage.java index 92d6493376..dbf8b5226c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/EndMeetingMessage.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/converters/messages/EndMeetingMessage.java @@ -1,12 +1,12 @@ package org.bigbluebutton.api.messaging.converters.messages; public class EndMeetingMessage { - public static final String END_MEETING_REQUEST_EVENT = "end_meeting_request_event"; - public static final String VERSION = "0.0.1"; + public static final String END_MEETING_REQUEST_EVENT = "end_meeting_request_event"; + public static final String VERSION = "0.0.1"; - public final String meetingId; - - public EndMeetingMessage(String meetingId) { - this.meetingId = meetingId; - } + public final String meetingId; + + public EndMeetingMessage(String meetingId) { + this.meetingId = meetingId; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java index 7cc51d53ee..08d6045e52 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java @@ -1,6 +1,10 @@ package org.bigbluebutton.api2; +import org.bigbluebutton.api.messaging.converters.messages.*; +import org.bigbluebutton.common.messages.SendStunTurnInfoReplyMessage; +import org.bigbluebutton.presentation.messages.IDocConversionMsg; + import java.util.Map; public interface IBbbWebApiGWApp { @@ -15,4 +19,13 @@ public interface IBbbWebApiGWApp { String dialNumber, Integer maxUsers); void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken, String avatarURL, Boolean guest, Boolean authed); + + void destroyMeeting(DestroyMeetingMessage msg); + void endMeeting(EndMeetingMessage msg); + void sendKeepAlive(String system, Long timestamp); + void publishRecording(PublishRecordingMessage msg); + void unpublishRecording(UnpublishRecordingMessage msg); + void deleteRecording(DeleteRecordingMessage msg); + void sendStunTurnInfoReply(SendStunTurnInfoReplyMessage msg); + void sendDocConversionMsg(IDocConversionMsg msg); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java index ce0a002fbd..e2c3130cb1 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/DocumentConversionServiceImp.java @@ -20,6 +20,7 @@ package org.bigbluebutton.presentation; import org.bigbluebutton.api.messaging.MessagingService; +import org.bigbluebutton.api2.IBbbWebApiGWApp; import org.bigbluebutton.presentation.imp.ImageToSwfSlidesGenerationService; import org.bigbluebutton.presentation.imp.OfficeToPdfConversionService; import org.bigbluebutton.presentation.imp.PdfToSwfSlidesGenerationService; @@ -30,13 +31,13 @@ public class DocumentConversionServiceImp implements DocumentConversionService { private static Logger log = LoggerFactory .getLogger(DocumentConversionServiceImp.class); - private MessagingService messagingService; + private IBbbWebApiGWApp gw; private OfficeToPdfConversionService officeToPdfConversionService; private PdfToSwfSlidesGenerationService pdfToSwfSlidesGenerationService; private ImageToSwfSlidesGenerationService imageToSwfSlidesGenerationService; public void processDocument(UploadedPresentation pres) { - SupportedDocumentFilter sdf = new SupportedDocumentFilter(messagingService); + SupportedDocumentFilter sdf = new SupportedDocumentFilter(gw); log.info("Start presentation conversion. meetingId=" + pres.getMeetingId() + " presId=" + pres.getId() + " name=" + pres.getName()); @@ -45,8 +46,7 @@ public class DocumentConversionServiceImp implements DocumentConversionService { if (SupportedFileTypes.isOfficeFile(fileType)) { pres = officeToPdfConversionService.convertOfficeToPdf(pres); - OfficeToPdfConversionSuccessFilter ocsf = new OfficeToPdfConversionSuccessFilter( - messagingService); + OfficeToPdfConversionSuccessFilter ocsf = new OfficeToPdfConversionSuccessFilter(gw); if (ocsf.didConversionSucceed(pres)) { // Successfully converted to pdf. Call the process again, this time it // should be handled by @@ -70,8 +70,8 @@ public class DocumentConversionServiceImp implements DocumentConversionService { } - public void setMessagingService(MessagingService m) { - messagingService = m; + public void setBbbWebApiGWApp(IBbbWebApiGWApp m) { + gw = m; } public void setOfficeToPdfConversionService(OfficeToPdfConversionService s) { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/OfficeToPdfConversionSuccessFilter.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/OfficeToPdfConversionSuccessFilter.java index 51ab8cbb5e..9552ad5bb3 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/OfficeToPdfConversionSuccessFilter.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/OfficeToPdfConversionSuccessFilter.java @@ -24,21 +24,22 @@ import java.util.Map; import org.bigbluebutton.api.messaging.MessagingConstants; import org.bigbluebutton.api.messaging.MessagingService; +import org.bigbluebutton.api2.IBbbWebApiGWApp; +import org.bigbluebutton.presentation.messages.OfficeDocConversionProgress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; public class OfficeToPdfConversionSuccessFilter { - private static Logger log = LoggerFactory - .getLogger(OfficeToPdfConversionSuccessFilter.class); + private static Logger log = LoggerFactory.getLogger(OfficeToPdfConversionSuccessFilter.class); - private final MessagingService messagingService; + private final IBbbWebApiGWApp gw; private static Map conversionMessagesMap; - public OfficeToPdfConversionSuccessFilter(MessagingService m) { - messagingService = m; + public OfficeToPdfConversionSuccessFilter(IBbbWebApiGWApp m) { + gw = m; conversionMessagesMap = new HashMap(); conversionMessagesMap.put( ConversionMessageConstants.OFFICE_DOC_CONVERSION_SUCCESS_KEY, @@ -70,18 +71,16 @@ public class OfficeToPdfConversionSuccessFilter { log.info("Notifying of " + pres.getConversionStatus() + " for " + pres.getUploadedFile().getAbsolutePath()); - sendNotification(msg); + sendProgress(pres); } - private void sendNotification(Map msg) { - if (messagingService != null) { - Gson gson = new Gson(); - String updateMsg = gson.toJson(msg); - log.debug("sending: " + updateMsg); - messagingService.send(MessagingConstants.TO_PRESENTATION_CHANNEL, - updateMsg); - } else { - log.warn("MessagingService has not been set!."); - } + + public void sendProgress(UploadedPresentation pres) { + OfficeDocConversionProgress progress = new OfficeDocConversionProgress(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), pres.getConversionStatus()); + gw.sendDocConversionMsg(progress); } + } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java index 2c915eba0f..fe9680e28f 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java @@ -1,21 +1,20 @@ /** -* 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 . -* -*/ + * 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 . + */ package org.bigbluebutton.presentation; @@ -24,54 +23,60 @@ import java.io.File; import org.apache.commons.io.FilenameUtils; import org.bigbluebutton.api.messaging.MessagingConstants; import org.bigbluebutton.api.messaging.MessagingService; +import org.bigbluebutton.api2.IBbbWebApiGWApp; import org.bigbluebutton.presentation.ConversionUpdateMessage.MessageBuilder; +import org.bigbluebutton.presentation.messages.OfficeDocConversionProgress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; public class SupportedDocumentFilter { - private static Logger log = LoggerFactory.getLogger(SupportedDocumentFilter.class); + private static Logger log = LoggerFactory.getLogger(SupportedDocumentFilter.class); - private final MessagingService messagingService; - - public SupportedDocumentFilter(MessagingService m) { - messagingService = m; - } - - public boolean isSupported(UploadedPresentation pres) { - File presentationFile = pres.getUploadedFile(); - - /* Get file extension - Perhaps try to rely on a more accurate method than an extension type ? */ - String extension = FilenameUtils.getExtension(presentationFile.getName()); - boolean supported = SupportedFileTypes.isFileSupported(extension); - notifyProgressListener(supported, pres); - if (supported) { - log.info("Received supported file {}", pres.getUploadedFile().getAbsolutePath()); - pres.setFileType(extension); - } - else { - log.warn("Received not supported file {}", pres.getUploadedFile().getAbsolutePath()); - } - return supported; - } - - private void notifyProgressListener(boolean supported, UploadedPresentation pres) { - MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); - - if (supported) { - builder.messageKey(ConversionMessageConstants.SUPPORTED_DOCUMENT_KEY); - } else { - builder.messageKey(ConversionMessageConstants.UNSUPPORTED_DOCUMENT_KEY); - } - - if(messagingService !=null){ - Gson gson= new Gson(); - String updateMsg=gson.toJson(builder.build().getMessage()); - log.debug("sending: "+updateMsg); - messagingService.send(MessagingConstants.TO_PRESENTATION_CHANNEL, updateMsg); - } else { - log.warn("MessagingService has not been set!"); - } - } + private final IBbbWebApiGWApp gw; + + public SupportedDocumentFilter(IBbbWebApiGWApp m) { + gw = m; + } + + public boolean isSupported(UploadedPresentation pres) { + File presentationFile = pres.getUploadedFile(); + + /* Get file extension - Perhaps try to rely on a more accurate method than an extension type ? */ + String extension = FilenameUtils.getExtension(presentationFile.getName()); + boolean supported = SupportedFileTypes.isFileSupported(extension); + notifyProgressListener(supported, pres); + if (supported) { + log.info("Received supported file {}", pres.getUploadedFile().getAbsolutePath()); + pres.setFileType(extension); + } else { + log.warn("Received not supported file {}", pres.getUploadedFile().getAbsolutePath()); + } + return supported; + } + + private void notifyProgressListener(boolean supported, UploadedPresentation pres) { + MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); + + String msgKey = ConversionMessageConstants.SUPPORTED_DOCUMENT_KEY; + + if (supported) { + msgKey = ConversionMessageConstants.SUPPORTED_DOCUMENT_KEY; + } else { + msgKey = ConversionMessageConstants.UNSUPPORTED_DOCUMENT_KEY; + } + + if (gw != null) { + OfficeDocConversionProgress progress = new OfficeDocConversionProgress(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), msgKey); + + gw.sendDocConversionMsg(progress); + + } else { + log.warn("MessagingService has not been set!"); + } + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/OfficeToPdfConversionService.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/OfficeToPdfConversionService.java index a74bfebf65..ebb7252edc 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/OfficeToPdfConversionService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/OfficeToPdfConversionService.java @@ -29,8 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class OfficeToPdfConversionService { - private static Logger log = LoggerFactory - .getLogger(OfficeToPdfConversionService.class); + private static Logger log = LoggerFactory.getLogger(OfficeToPdfConversionService.class); private OfficeDocumentValidator officeDocumentValidator; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java index a1e6995f73..48e7dc38dd 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/PdfToSwfSlidesGenerationService.java @@ -42,14 +42,15 @@ import org.bigbluebutton.presentation.SvgImageCreator; import org.bigbluebutton.presentation.TextFileCreator; import org.bigbluebutton.presentation.ThumbnailCreator; import org.bigbluebutton.presentation.UploadedPresentation; +import org.bigbluebutton.presentation.messages.DocPageCountExceeded; +import org.bigbluebutton.presentation.messages.DocPageCountFailed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; public class PdfToSwfSlidesGenerationService { - private static Logger log = LoggerFactory - .getLogger(PdfToSwfSlidesGenerationService.class); + private static Logger log = LoggerFactory.getLogger(PdfToSwfSlidesGenerationService.class); private SwfSlidesGenerationProgressNotifier notifier; private PageCounterService counterService; @@ -94,20 +95,33 @@ public class PdfToSwfSlidesGenerationService { return false; } - private void sendFailedToCountPageMessage(CountingPageException e, - UploadedPresentation pres) { + private void sendFailedToCountPageMessage(CountingPageException e, UploadedPresentation pres) { MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); - if (e - .getExceptionType() == CountingPageException.ExceptionType.PAGE_COUNT_EXCEPTION) { + if (e.getExceptionType() == CountingPageException.ExceptionType.PAGE_COUNT_EXCEPTION) { builder.messageKey(ConversionMessageConstants.PAGE_COUNT_FAILED_KEY); - } else if (e - .getExceptionType() == CountingPageException.ExceptionType.PAGE_EXCEEDED_EXCEPTION) { + + DocPageCountFailed progress = new DocPageCountFailed(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), ConversionMessageConstants.PAGE_COUNT_FAILED_KEY); + + notifier.sendDocConversionProgress(progress); + + } else if (e.getExceptionType() == CountingPageException.ExceptionType.PAGE_EXCEEDED_EXCEPTION) { builder.numberOfPages(e.getPageCount()); builder.maxNumberPages(e.getMaxNumberOfPages()); builder.messageKey(ConversionMessageConstants.PAGE_COUNT_EXCEEDED_KEY); + + DocPageCountExceeded progress = new DocPageCountExceeded(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), ConversionMessageConstants.PAGE_COUNT_EXCEEDED_KEY, + e.getPageCount(), e.getMaxNumberOfPages()); + + notifier.sendDocConversionProgress(progress); } - notifier.sendConversionUpdateMessage(builder.build().getMessage()); + } private void createThumbnails(UploadedPresentation pres) { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java index c85d669566..5320353781 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/SwfSlidesGenerationProgressNotifier.java @@ -1,103 +1,103 @@ /** -* 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 . -* -*/ + * 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 . + */ package org.bigbluebutton.presentation.imp; -import java.util.Map; - -import org.bigbluebutton.api.messaging.MessagingConstants; -import org.bigbluebutton.api.messaging.MessagingService; +import org.bigbluebutton.api2.IBbbWebApiGWApp; 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.messages.DocPageCompletedProgress; +import org.bigbluebutton.presentation.messages.DocPageGeneratedProgress; +import org.bigbluebutton.presentation.messages.IDocConversionMsg; +import org.bigbluebutton.presentation.messages.OfficeDocConversionProgress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; - public class SwfSlidesGenerationProgressNotifier { - private static Logger log = LoggerFactory.getLogger(SwfSlidesGenerationProgressNotifier.class); + private static Logger log = LoggerFactory.getLogger(SwfSlidesGenerationProgressNotifier.class); - private MessagingService messagingService; - - private GeneratedSlidesInfoHelper generatedSlidesInfoHelper; - - private void notifyProgressListener(Map msg) { - if(messagingService != null){ - Gson gson= new Gson(); - String updateMsg = gson.toJson(msg); - messagingService.send(MessagingConstants.TO_PRESENTATION_CHANNEL, updateMsg); - } else { - log.warn("MessagingService has not been set"); - } - } + private IBbbWebApiGWApp messagingService; - public void sendConversionUpdateMessage(Map message) { - notifyProgressListener(message); - } - - public void sendConversionUpdateMessage(int slidesCompleted, UploadedPresentation pres) { - MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); - builder.messageKey(ConversionMessageConstants.GENERATED_SLIDE_KEY); - builder.numberOfPages(pres.getNumberOfPages()); - builder.pagesCompleted(slidesCompleted); - notifyProgressListener(builder.build().getMessage()); - } - - public void sendCreatingThumbnailsUpdateMessage(UploadedPresentation pres) { - MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); - builder.messageKey(ConversionMessageConstants.GENERATING_THUMBNAIL_KEY); - notifyProgressListener(builder.build().getMessage()); - } - - public void sendConversionCompletedMessage(UploadedPresentation pres) { - if (generatedSlidesInfoHelper == null) { - log.error("GeneratedSlidesInfoHelper was not set. Could not notify interested listeners."); - return; - } - - MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); - builder.messageKey(ConversionMessageConstants.CONVERSION_COMPLETED_KEY); - builder.numberOfPages(pres.getNumberOfPages()); - builder.presBaseUrl(pres); - notifyProgressListener(builder.build().getMessage()); - } - - public void setMessagingService(MessagingService m) { - messagingService = m; - } - - public void setGeneratedSlidesInfoHelper(GeneratedSlidesInfoHelper helper) { - generatedSlidesInfoHelper = helper; - } + private GeneratedSlidesInfoHelper generatedSlidesInfoHelper; - public void sendCreatingTextFilesUpdateMessage(UploadedPresentation pres) { - MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); - builder.messageKey(ConversionMessageConstants.GENERATING_TEXTFILES_KEY); - notifyProgressListener(builder.build().getMessage()); - } - public void sendCreatingSvgImagesUpdateMessage(UploadedPresentation pres) { - MessageBuilder builder = new ConversionUpdateMessage.MessageBuilder(pres); - builder.messageKey(ConversionMessageConstants.GENERATING_SVGIMAGES_KEY); - notifyProgressListener(builder.build().getMessage()); - } + public void sendDocConversionProgress(IDocConversionMsg msg) { + messagingService.sendDocConversionMsg(msg); + } + + + public void sendConversionUpdateMessage(int slidesCompleted, UploadedPresentation pres) { + DocPageGeneratedProgress progress = new DocPageGeneratedProgress(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), ConversionMessageConstants.GENERATED_SLIDE_KEY, + pres.getNumberOfPages(), slidesCompleted); + messagingService.sendDocConversionMsg(progress); + } + + public void sendCreatingThumbnailsUpdateMessage(UploadedPresentation pres) { + OfficeDocConversionProgress progress = new OfficeDocConversionProgress(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), ConversionMessageConstants.GENERATING_THUMBNAIL_KEY); + messagingService.sendDocConversionMsg(progress); + } + + public void sendConversionCompletedMessage(UploadedPresentation pres) { + if (generatedSlidesInfoHelper == null) { + log.error("GeneratedSlidesInfoHelper was not set. Could not notify interested listeners."); + return; + } + + DocPageCompletedProgress progress = new DocPageCompletedProgress(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), ConversionMessageConstants.CONVERSION_COMPLETED_KEY, + pres.getNumberOfPages(), generateBasePresUrl(pres)); + messagingService.sendDocConversionMsg(progress); + } + + private String generateBasePresUrl(UploadedPresentation pres) { + return pres.getBaseUrl() + "/" + pres.getMeetingId() + "/" + pres.getMeetingId() + "/" + pres.getId(); + } + + public void setMessagingService(IBbbWebApiGWApp m) { + messagingService = m; + } + + public void setGeneratedSlidesInfoHelper(GeneratedSlidesInfoHelper helper) { + generatedSlidesInfoHelper = helper; + } + + public void sendCreatingTextFilesUpdateMessage(UploadedPresentation pres) { + OfficeDocConversionProgress progress = new OfficeDocConversionProgress(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), ConversionMessageConstants.GENERATING_TEXTFILES_KEY); + messagingService.sendDocConversionMsg(progress); + } + + public void sendCreatingSvgImagesUpdateMessage(UploadedPresentation pres) { + OfficeDocConversionProgress progress = new OfficeDocConversionProgress(pres.getMeetingId(), + pres.getId(), pres.getId(), + pres.getName(), "notUsedYet", "notUsedYet", + pres.isDownloadable(), ConversionMessageConstants.GENERATING_SVGIMAGES_KEY); + messagingService.sendDocConversionMsg(progress); + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCompletedProgress.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCompletedProgress.java new file mode 100755 index 0000000000..9a8d64f906 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCompletedProgress.java @@ -0,0 +1,30 @@ +package org.bigbluebutton.presentation.messages; + +public class DocPageCompletedProgress implements IDocConversionMsg { + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + public final String key; + public final Integer numPages; + public final String presBaseUrl; + + public DocPageCompletedProgress(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable, String key, + Integer numPages, String presBaseUrl) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + this.key = key; + this.numPages = numPages; + this.presBaseUrl = presBaseUrl; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCountExceeded.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCountExceeded.java new file mode 100755 index 0000000000..a36ef9cda0 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCountExceeded.java @@ -0,0 +1,30 @@ +package org.bigbluebutton.presentation.messages; + +public class DocPageCountExceeded implements IDocConversionMsg { + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + public final String key; + public final Integer numPages; + public final Integer maxNumPages; + + public DocPageCountExceeded(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable, String key, + Integer numPages, Integer maxNumPages) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + this.key = key; + this.numPages = numPages; + this.maxNumPages = maxNumPages; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCountFailed.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCountFailed.java new file mode 100755 index 0000000000..fcc8806087 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageCountFailed.java @@ -0,0 +1,25 @@ +package org.bigbluebutton.presentation.messages; + +public class DocPageCountFailed implements IDocConversionMsg { + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + public final String key; + + public DocPageCountFailed(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable, String key) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + this.key = key; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageGeneratedProgress.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageGeneratedProgress.java new file mode 100755 index 0000000000..e9ef860549 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/DocPageGeneratedProgress.java @@ -0,0 +1,30 @@ +package org.bigbluebutton.presentation.messages; + +public class DocPageGeneratedProgress implements IDocConversionMsg { + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + public final String key; + public final Integer numPages; + public final Integer pagesCompleted; + + public DocPageGeneratedProgress(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable, String key, + Integer numPages, Integer pagesCompleted) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + this.key = key; + this.numPages = numPages; + this.pagesCompleted = pagesCompleted; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/IDocConversionMsg.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/IDocConversionMsg.java new file mode 100755 index 0000000000..f407ffa82e --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/IDocConversionMsg.java @@ -0,0 +1,5 @@ +package org.bigbluebutton.presentation.messages; + + +public interface IDocConversionMsg { +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionInvalid.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionInvalid.java new file mode 100755 index 0000000000..826af2c8d0 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionInvalid.java @@ -0,0 +1,26 @@ +package org.bigbluebutton.presentation.messages; + + +import org.bigbluebutton.api.messaging.messages.IMessage; + +public class OfficeDocConversionInvalid implements IMessage{ + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + + public OfficeDocConversionInvalid(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionProgress.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionProgress.java new file mode 100755 index 0000000000..a42a5b4816 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionProgress.java @@ -0,0 +1,28 @@ +package org.bigbluebutton.presentation.messages; + + +import org.bigbluebutton.api.messaging.messages.IMessage; + +public class OfficeDocConversionProgress implements IDocConversionMsg { + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + public final String key; + + public OfficeDocConversionProgress(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable, String key) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + this.key = key; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionSuccess.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionSuccess.java new file mode 100755 index 0000000000..f79bab478c --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionSuccess.java @@ -0,0 +1,26 @@ +package org.bigbluebutton.presentation.messages; + + +import org.bigbluebutton.api.messaging.messages.IMessage; + +public class OfficeDocConversionSuccess implements IMessage{ + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + + public OfficeDocConversionSuccess(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionSupported.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionSupported.java new file mode 100755 index 0000000000..ef9718ab3e --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionSupported.java @@ -0,0 +1,26 @@ +package org.bigbluebutton.presentation.messages; + + +import org.bigbluebutton.api.messaging.messages.IMessage; + +public class OfficeDocConversionSupported implements IMessage{ + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + + public OfficeDocConversionSupported(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionUnsupported.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionUnsupported.java new file mode 100755 index 0000000000..70599a0247 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/messages/OfficeDocConversionUnsupported.java @@ -0,0 +1,26 @@ +package org.bigbluebutton.presentation.messages; + + +import org.bigbluebutton.api.messaging.messages.IMessage; + +public class OfficeDocConversionUnsupported implements IMessage{ + public final String meetingId; + public final String presId; + public final String presInstance; + public final String filename; + public final String uploaderId; + public final String authzToken; + public final Boolean downloadable; + + public OfficeDocConversionUnsupported(String meetingId, String presId, String presInstance, + String filename, String uploaderId, String authzToken, + Boolean downloadable) { + this.meetingId = meetingId; + this.presId = presId; + this.presInstance = presInstance; + this.filename = filename; + this.uploaderId = uploaderId; + this.authzToken = authzToken; + this.downloadable = downloadable; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/KeepAliveService.java b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/KeepAliveService.java index b048a4a774..1a79cbfba4 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/KeepAliveService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/KeepAliveService.java @@ -1,21 +1,20 @@ /** -* 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 . -* -*/ + * 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 . + */ package org.bigbluebutton.web.services; @@ -25,141 +24,138 @@ import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; - 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.bigbluebutton.api.pub.IPublisherService; +import org.bigbluebutton.api2.IBbbWebApiGWApp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class KeepAliveService implements MessageListener { - private static Logger log = LoggerFactory.getLogger(KeepAliveService.class); - private final String KEEP_ALIVE_REQUEST = "KEEP_ALIVE_REQUEST"; - private MessagingService service; - private long runEvery = 10000; - private int maxLives = 5; - private KeepAliveTask task = new KeepAliveTask(); - private volatile boolean processMessages = false; + private static Logger log = LoggerFactory.getLogger(KeepAliveService.class); + private final String KEEP_ALIVE_REQUEST = "KEEP_ALIVE_REQUEST"; + private IBbbWebApiGWApp gw; + private long runEvery = 10000; + private int maxLives = 5; + private KeepAliveTask task = new KeepAliveTask(); + private volatile boolean processMessages = false; - volatile boolean available = true; - - private static final Executor msgSenderExec = Executors.newFixedThreadPool(1); - private static final Executor runExec = Executors.newFixedThreadPool(1); - - private ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1); - - private BlockingQueue messages = new LinkedBlockingQueue(); - - private Long lastKeepAliveMessage = 0L; - - private final String SYSTEM = "BbbWeb"; - - public void start() { - scheduledThreadPool.scheduleWithFixedDelay(task, 5000, runEvery, TimeUnit.MILLISECONDS); - processKeepAliveMessage(); - } - - public void stop() { - processMessages = false; - scheduledThreadPool.shutdownNow(); - } - - public void setRunEvery(long v) { - runEvery = v * 1000; - } + volatile boolean available = true; - public void setPublisherService(MessagingService service){ - this.service = service; - } - - class KeepAliveTask implements Runnable { + private static final Executor msgSenderExec = Executors.newFixedThreadPool(1); + private static final Executor runExec = Executors.newFixedThreadPool(1); + + private ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1); + + private BlockingQueue messages = new LinkedBlockingQueue(); + + private Long lastKeepAliveMessage = 0L; + + private final String SYSTEM = "BbbWeb"; + + public void start() { + scheduledThreadPool.scheduleWithFixedDelay(task, 5000, runEvery, TimeUnit.MILLISECONDS); + processKeepAliveMessage(); + } + + public void stop() { + processMessages = false; + scheduledThreadPool.shutdownNow(); + } + + public void setRunEvery(long v) { + runEvery = v * 1000; + } + + public void setGw(IBbbWebApiGWApp gw) { + this.gw = gw; + } + + class KeepAliveTask implements Runnable { public void run() { - KeepAlivePing ping = new KeepAlivePing(); - queueMessage(ping); + KeepAlivePing ping = new KeepAlivePing(); + queueMessage(ping); } } - public boolean isDown(){ - //return !available; - return false; + public boolean isDown() { + //return !available; + return false; } - + private void queueMessage(KeepAliveMessage msg) { - messages.add(msg); + messages.add(msg); } - + private void processKeepAliveMessage() { - processMessages = true; - Runnable sender = new Runnable() { - public void run() { - while (processMessages) { - KeepAliveMessage message; - try { - message = messages.take(); - processMessage(message); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (Exception e) { - log.error("Catching exception [{}]", e.toString()); - } - } - } - }; - msgSenderExec.execute(sender); - } - + processMessages = true; + Runnable sender = new Runnable() { + public void run() { + while (processMessages) { + KeepAliveMessage message; + try { + message = messages.take(); + processMessage(message); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (Exception e) { + log.error("Catching exception [{}]", e.toString()); + } + } + } + }; + msgSenderExec.execute(sender); + } + private void processMessage(final KeepAliveMessage msg) { - Runnable task = new Runnable() { - public void run() { - if (msg instanceof KeepAlivePing) { -// processPing((KeepAlivePing) msg); - } else if (msg instanceof KeepAlivePong) { -// processPong((KeepAlivePong) msg); - } - } - }; - + Runnable task = new Runnable() { + public void run() { + if (msg instanceof KeepAlivePing) { + processPing((KeepAlivePing) msg); + } else if (msg instanceof KeepAlivePong) { + processPong((KeepAlivePong) msg); + } + } + }; + runExec.execute(task); } - + private void processPing(KeepAlivePing msg) { - service.sendKeepAlive(SYSTEM, System.currentTimeMillis()); - Boolean akkaAppsIsAvailable = available; + gw.sendKeepAlive(SYSTEM, System.currentTimeMillis()); + Boolean akkaAppsIsAvailable = available; - if (lastKeepAliveMessage != 0 && (System.currentTimeMillis() - lastKeepAliveMessage > 30000)) { - if (akkaAppsIsAvailable) { - log.error("BBB Web pubsub error!"); - // BBB-Apps has gone down. Mark it as unavailable. (ralam - april 29, 2014) - available = false; - } - } + if (lastKeepAliveMessage != 0 && (System.currentTimeMillis() - lastKeepAliveMessage > 30000)) { + if (akkaAppsIsAvailable) { + log.error("BBB Web pubsub error!"); + // BBB-Apps has gone down. Mark it as unavailable. (ralam - april 29, 2014) + available = false; + } + } } - + private void processPong(KeepAlivePong msg) { - if (lastKeepAliveMessage != 0 && !available) { - log.error("BBB Web pubsub recovered!"); - } - - lastKeepAliveMessage = System.currentTimeMillis(); - available = true; - } - - private void handleKeepAliveReply(String system, Long timestamp) { - if (system.equals("BbbWeb")) { - KeepAlivePong pong = new KeepAlivePong(system, timestamp); - queueMessage(pong); - } + if (lastKeepAliveMessage != 0 && !available) { + log.error("BBB Web pubsub recovered!"); + } + lastKeepAliveMessage = System.currentTimeMillis(); + available = true; } - - @Override + + private void handleKeepAliveReply(String system, Long timestamp) { + if (system.equals("BbbWeb")) { + KeepAlivePong pong = new KeepAlivePong(system, timestamp); + queueMessage(pong); + } + } + + @Override public void handle(IMessage message) { - if (message instanceof KeepAliveReply) { - KeepAliveReply msg = (KeepAliveReply) message; - handleKeepAliveReply(msg.system, msg.timestamp); - } + if (message instanceof KeepAliveReply) { + KeepAliveReply msg = (KeepAliveReply) message; + handleKeepAliveReply(msg.system, msg.timestamp); + } } } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala index bebc827cf2..075e6d4bfb 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala @@ -3,10 +3,13 @@ package org.bigbluebutton.api2 import scala.collection.JavaConverters._ import akka.actor.ActorSystem import akka.event.Logging +import org.bigbluebutton.api.messaging.converters.messages._ import org.bigbluebutton.api2.bus._ import org.bigbluebutton.api2.endpoint.redis.{AppsRedisSubscriberActor, MessageSender, RedisPublisher} -import org.bigbluebutton.api2.meeting.{CreateMeetingMsg, MeetingsManagerActor, RegisterUser} +import org.bigbluebutton.api2.meeting.{MeetingsManagerActor, OldMeetingMsgHdlrActor, RegisterUser} +import org.bigbluebutton.common.messages.SendStunTurnInfoReplyMessage import org.bigbluebutton.common2.domain._ +import org.bigbluebutton.presentation.messages.IDocConversionMsg import scala.concurrent.duration._ @@ -24,8 +27,7 @@ class BbbWebApiGWApp(val oldMessageReceivedGW: OldMessageReceivedGW) extends IBb private val jsonMsgToAkkaAppsBus = new JsonMsgToAkkaAppsBus private val redisPublisher = new RedisPublisher(system) private val msgSender: MessageSender = new MessageSender(redisPublisher) - private val messageSenderActorRef = system.actorOf( - MessageSenderActor.props(msgSender), "messageSenderActor") + private val messageSenderActorRef = system.actorOf(MessageSenderActor.props(msgSender), "messageSenderActor") jsonMsgToAkkaAppsBus.subscribe(messageSenderActorRef, toAkkaAppsJsonChannel) @@ -38,6 +40,11 @@ class BbbWebApiGWApp(val oldMessageReceivedGW: OldMessageReceivedGW) extends IBb MeetingsManagerActor.props(msgToAkkaAppsEventBus), "meetingManagerActor") msgFromAkkaAppsEventBus.subscribe(meetingManagerActorRef, fromAkkaAppsChannel) + private val oldMeetingMsgHdlrActor = system.actorOf( + OldMeetingMsgHdlrActor.props(oldMessageReceivedGW), "oldMeetingMsgHdlrActor" + ) + msgFromAkkaAppsEventBus.subscribe(oldMeetingMsgHdlrActor, fromAkkaAppsChannel) + private val msgToAkkaAppsToJsonActor = system.actorOf( MsgToAkkaAppsToJsonActor.props(jsonMsgToAkkaAppsBus), "msgToAkkaAppsToJsonActor") @@ -94,14 +101,58 @@ class BbbWebApiGWApp(val oldMessageReceivedGW: OldMessageReceivedGW) extends IBb val defaultProps = DefaultProps(meetingProp, breakoutProps, durationProps, password, recordProp, welcomeProp, voiceProp, usersProp, metadataProp, screenshareProps) - meetingManagerActorRef ! new CreateMeetingMsg(defaultProps) + //meetingManagerActorRef ! new CreateMeetingMsg(defaultProps) + + val event = MsgBuilder.buildCreateMeetingRequestToAkkaApps(defaultProps) + msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) + } def registerUser (meetingId: String, intUserId: String, name: String, role: String, extUserId: String, authToken: String, avatarURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean): Unit = { - meetingManagerActorRef ! new RegisterUser(meetingId = meetingId, intUserId = intUserId, name = name, - role = role, extUserId = extUserId, authToken = authToken, avatarURL = avatarURL, - guest = guest, authed = authed) + +// meetingManagerActorRef ! new RegisterUser(meetingId = meetingId, intUserId = intUserId, name = name, +// role = role, extUserId = extUserId, authToken = authToken, avatarURL = avatarURL, +// guest = guest, authed = authed) + + val regUser = new RegisterUser(meetingId = meetingId, intUserId = intUserId, name = name, + role = role, extUserId = extUserId, authToken = authToken, avatarURL = avatarURL, + guest = guest.booleanValue(), authed = authed.booleanValue()) + + val event = MsgBuilder.buildRegisterUserRequestToAkkaApps(regUser) + msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) + } + + def destroyMeeting (msg: DestroyMeetingMessage): Unit = { + + } + + def endMeeting(msg: EndMeetingMessage): Unit = { + + } + + def sendKeepAlive(system: String, timestamp: java.lang.Long): Unit = { + + } + + def publishRecording(msg: PublishRecordingMessage): Unit = { + + } + + def unpublishRecording(msg: UnpublishRecordingMessage): Unit = { + + } + + def deleteRecording(msg: DeleteRecordingMessage): Unit = { + + } + + def sendStunTurnInfoReply(msg: SendStunTurnInfoReplyMessage): Unit = { + + } + + def sendDocConversionMsg(msg: IDocConversionMsg): Unit = { + } } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala new file mode 100755 index 0000000000..f0443b071b --- /dev/null +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala @@ -0,0 +1,29 @@ +package org.bigbluebutton.api2 + +import org.bigbluebutton.api2.meeting.RegisterUser +import org.bigbluebutton.common2.domain.DefaultProps +import org.bigbluebutton.common2.msgs._ + + +object MsgBuilder { + def buildCreateMeetingRequestToAkkaApps(props: DefaultProps): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-web") + val envelope = BbbCoreEnvelope(CreateMeetingReqMsg.NAME, routing) + val header = BbbCoreBaseHeader(CreateMeetingReqMsg.NAME) + val body = CreateMeetingReqMsgBody(props) + val req = CreateMeetingReqMsg(header, body) + BbbCommonEnvCoreMsg(envelope, req) + } + + def buildRegisterUserRequestToAkkaApps(msg: RegisterUser): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-web") + val envelope = BbbCoreEnvelope(RegisterUserReqMsg.NAME, routing) + val header = BbbCoreHeaderWithMeetingId(RegisterUserReqMsg.NAME, msg.meetingId) + val body = RegisterUserReqMsgBody(meetingId = msg.meetingId, intUserId = msg.intUserId, + name = msg.name, role = msg.role, extUserId = msg.extUserId, authToken = msg.authToken, + avatarURL = msg.avatarURL, guest = msg.guest, authed = msg.authed) + val req = RegisterUserReqMsg(header, body) + BbbCommonEnvCoreMsg(envelope, req) + } + +} diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala index e4e2f908fb..f996ad30ef 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageJsonReceiverActor.scala @@ -9,6 +9,6 @@ object OldMessageJsonReceiverActor{ class OldMessageJsonReceiverActor(gw: OldMessageReceivedGW) extends Actor with ActorLogging { def receive = { - case msg: OldReceivedJsonMessage => gw.handle(msg.pattern, msg.channel, msg.msg) + case msg: OldReceivedJsonMessage => //gw.handle(msg.pattern, msg.channel, msg.msg) } } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageReceivedGW.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageReceivedGW.scala index df54ee3877..4305bf3174 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageReceivedGW.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/OldMessageReceivedGW.scala @@ -1,11 +1,13 @@ package org.bigbluebutton.api2.bus import org.bigbluebutton.api.IReceivedOldMessageHandler +import org.bigbluebutton.api.messaging.messages.IMessage class OldMessageReceivedGW(handler: IReceivedOldMessageHandler) { - def handle(pattern: String, channel: String, msg: String): Unit = { - handler.handleMessage(pattern, channel, msg) + def handle(msg: IMessage): Unit = { + handler.handleMessage(msg) } + } 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 new file mode 100755 index 0000000000..c1cd499c4e --- /dev/null +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala @@ -0,0 +1,103 @@ +package org.bigbluebutton.api2.meeting + +import akka.actor.{Actor, ActorLogging, Props} +import org.bigbluebutton.api2.bus.OldMessageReceivedGW +import org.bigbluebutton.common2.msgs._ + + +object OldMeetingMsgHdlrActor { + def props(olgMsgGW: OldMessageReceivedGW): Props = + Props(classOf[OldMeetingMsgHdlrActor], olgMsgGW) +} + +class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) + extends Actor with ActorLogging { + + + def receive = { + case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg) + } + + private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = { + msg.core match { + case m: MeetingCreatedEvtMsg => handleMeetingCreatedEvtMsg(m) + case _ => log.error("***** Cannot handle " + msg.envelope.name) + } + } + + def handleMeetingCreatedEvtMsg(msg: MeetingCreatedEvtMsg): Unit = { + // listener.handle(new MeetingStarted(meetingId)) + } + + def handleMeetingEndedEvtMsg(msg: MeetingEndedEvtMsg): Unit = { + // listener.handle(new MeetingEnded(meetingId)) + } + + def handleMeetingDestroyedEvtMsg(msg: MeetingDestroyedEvtMsg): Unit = { + // listener.handle(new MeetingDestroyed(meetingId)) + } + +// def handleCreateBreakoutRoomSysCmdMsg(msg: CreateBreakoutRoomSysCmdMsg): Unit = { + /* listener.handle(new CreateBreakoutRoom( + msg.payload.breakoutMeetingId, + msg.payload.parentMeetingId, + 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 + ) + ); + */ +// } + +// def handleEndBreakoutRoomSysCmdMsg(msg: EndBreakoutRoomSysCmdMsg): Unit = { + //listener.handle(new EndBreakoutRoom(msg.payload.meetingId)) +// } + +// def handlePubSubPongSysRespMsg(msg: PubSubPongSysRespMsg): Unit = { + // new KeepAliveReply(m.payload.system, m.payload.timestamp) +// } + +// def handleUserJoinedMeetingEvtMsg(msg: UserJoinedMeetingEvtMsg): Unit = { + // listener.handle(new UserJoined(meetingId, userid, externuserid, username, role, avatarURL, guest, waitingForAcceptance)); + +// } + +// def handleUserStausChangedEvtMsg(msg: UserStatusChangedEvtMsg): Unit = { + //listener.handle(new UserStatusChanged(meetingId, userid, status, value)) +// } + +// def handleUserLeftMeetingEvtMsg(msg: UserLeftMeetingEvtMsg): Unit = { + // listener.handle(new UserLeft(meetingId, userid)) +// } + + /** + * for (MessageListener listener : listeners) { + listener.handle(new UserJoinedVoice(meetingId, userid)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserLeftVoice(meetingId, userid)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserListeningOnly(meetingId, userid, listenOnly)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserSharedWebcam(meetingId, userid, stream)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserUnsharedWebcam(meetingId, userid, stream)); + } + for (MessageListener listener : listeners) { + listener.handle(new UserRoleChanged(meetingId, userid, role)); + } + for (MessageListener listener : listeners) { + listener.handle(new StunTurnInfoRequested(meetingId, requesterId)); + } + */ + +} diff --git a/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml b/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml index a406431d07..3c8c2765b3 100755 --- a/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml +++ b/bigbluebutton-web/grails-app/conf/spring/bbb-redis-messaging.xml @@ -19,42 +19,14 @@ with BigBlueButton; if not, see . --> - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bigbluebutton-web/grails-app/conf/spring/doc-conversion.xml b/bigbluebutton-web/grails-app/conf/spring/doc-conversion.xml index 6b87990553..43e925b6fe 100755 --- a/bigbluebutton-web/grails-app/conf/spring/doc-conversion.xml +++ b/bigbluebutton-web/grails-app/conf/spring/doc-conversion.xml @@ -19,88 +19,91 @@ with BigBlueButton; if not, see . --> - - - - - - - - - - - - - - - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bigbluebutton-web/grails-app/conf/spring/resources.xml b/bigbluebutton-web/grails-app/conf/spring/resources.xml index 23e33e5a4a..745e0e1950 100755 --- a/bigbluebutton-web/grails-app/conf/spring/resources.xml +++ b/bigbluebutton-web/grails-app/conf/spring/resources.xml @@ -19,99 +19,115 @@ with BigBlueButton; if not, see . --> + http://www.springframework.org/schema/util/spring-util-2.0.xsd"> - - - - - - - - + init-method="start" destroy-method="stop"> - + - + - + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +