Merge pull request #632 from daronco/api-merges

API merges
This commit is contained in:
Richard Alam 2015-08-06 17:58:34 -04:00
commit 00c5cac9c9
13 changed files with 360 additions and 13 deletions

View File

@ -123,6 +123,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
case msg: UserJoined => handleUserJoined(msg)
case msg: UserRaisedHand => handleUserRaisedHand(msg)
case msg: UserLoweredHand => handleUserLoweredHand(msg)
case msg: UserListeningOnly => handleUserListeningOnly(msg)
case msg: UserSharedWebcam => handleUserSharedWebcam(msg)
case msg: UserUnsharedWebcam => handleUserUnsharedWebcam(msg)
case msg: UserStatusChange => handleUserStatusChange(msg)
@ -1616,6 +1617,21 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
// println("***** DISPATCHING USER LOWERED HAND *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleUserListeningOnly(msg: UserListeningOnly) {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.USER_ID, msg.userID)
payload.put(Constants.LISTEN_ONLY, msg.listenOnly)
val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.USER_LISTEN_ONLY)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
header.put(Constants.CURRENT_TIME, TimestampGenerator.getCurrentTime)
// println("***** DISPATCHING USER LISTENING ONLY *****************")
dispatcher.dispatch(buildJson(header, payload))
}
private def handleUserSharedWebcam(msg: UserSharedWebcam) {
val payload = new java.util.HashMap[String, Any]()

View File

@ -807,10 +807,16 @@ class ApiController {
meetingName(m.getName())
createTime(m.getCreateTime())
createDate(formatPrettyDate(m.getCreateTime()))
voiceBridge(m.getTelVoice())
dialNumber(m.getDialNumber())
attendeePW(m.getViewerPassword())
moderatorPW(m.getModeratorPassword())
hasBeenForciblyEnded(m.isForciblyEnded() ? "true" : "false")
running(m.isRunning() ? "true" : "false")
participantCount(m.getNumUsers())
listenerCount(m.getNumListenOnly())
voiceParticipantCount(m.getNumVoiceJoined())
videoCount(m.getNumVideos())
duration(m.duration)
hasUserJoined(m.hasUserJoined())
}
@ -1652,6 +1658,7 @@ class ApiController {
// Everything is good so far. Translate the external meeting ids to an internal meeting ids.
ArrayList<String> internalMeetingIds = paramsProcessorUtil.convertToInternalMeetingId(externalMeetingIds);
HashMap<String,Recording> recs = meetingService.getRecordings(internalMeetingIds);
recs = meetingService.filterRecordingsByMetadata(recs, ParamsProcessorUtil.processMetaParam(params));
if (recs.isEmpty()) {
response.addHeader("Cache-Control", "no-cache")
@ -1987,6 +1994,7 @@ class ApiController {
returncode(RESP_CODE_SUCCESS)
meetingName(meeting.getName())
meetingID(meeting.getExternalId())
internalMeetingID(meeting.getInternalId())
createTime(meeting.getCreateTime())
createDate(formatPrettyDate(meeting.getCreateTime()))
voiceBridge(meeting.getTelVoice())
@ -2001,6 +2009,9 @@ class ApiController {
startTime(meeting.getStartTime())
endTime(meeting.getEndTime())
participantCount(meeting.getNumUsers())
listenerCount(meeting.getNumListenOnly())
voiceParticipantCount(meeting.getNumVoiceJoined())
videoCount(meeting.getNumVideos())
maxUsers(meeting.getMaxUsers())
moderatorCount(meeting.getNumModerators())
attendees() {
@ -2009,6 +2020,10 @@ class ApiController {
userID("${att.externalUserId}")
fullName("${att.fullname}")
role("${att.role}")
isPresenter("${att.isPresenter()}")
isListeningOnly("${att.isListeningOnly()}")
hasJoinedVoice("${att.isVoiceJoined()}")
hasVideo("${att.hasVideo()}")
customdata(){
meeting.getUserCustomData(att.externalUserId).each{ k,v ->
"$k"("$v")
@ -2042,6 +2057,8 @@ class ApiController {
attendeePW(meeting.getViewerPassword())
moderatorPW(meeting.getModeratorPassword())
createTime(meeting.getCreateTime())
voiceBridge(meeting.getTelVoice())
dialNumber(meeting.getDialNumber())
createDate(formatPrettyDate(meeting.getCreateTime()))
hasUserJoined(meeting.hasUserJoined())
duration(meeting.duration)

View File

@ -21,6 +21,14 @@ package org.bigbluebutton.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -28,16 +36,14 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.*;
import org.bigbluebutton.api.domain.Meeting;
import org.bigbluebutton.api.domain.Playback;
import org.bigbluebutton.api.domain.Recording;
import org.bigbluebutton.api.domain.User;
import org.bigbluebutton.api.domain.UserSession;
import org.bigbluebutton.api.messaging.MessageListener;
import org.bigbluebutton.api.messaging.MessagingConstants;
import org.bigbluebutton.api.messaging.MessagingService;
import org.bigbluebutton.api.messaging.ReceivedMessage;
import org.bigbluebutton.api.messaging.messages.CreateMeeting;
import org.bigbluebutton.api.messaging.messages.EndMeeting;
import org.bigbluebutton.api.messaging.messages.IMessage;
@ -47,10 +53,14 @@ import org.bigbluebutton.api.messaging.messages.MeetingStarted;
import org.bigbluebutton.api.messaging.messages.RegisterUser;
import org.bigbluebutton.api.messaging.messages.RemoveExpiredMeetings;
import org.bigbluebutton.api.messaging.messages.UserJoined;
import org.bigbluebutton.api.messaging.messages.UserJoinedVoice;
import org.bigbluebutton.api.messaging.messages.UserLeft;
import org.bigbluebutton.api.messaging.messages.UserLeftVoice;
import org.bigbluebutton.api.messaging.messages.UserListeningOnly;
import org.bigbluebutton.api.messaging.messages.UserSharedWebcam;
import org.bigbluebutton.api.messaging.messages.UserStatusChanged;
import org.bigbluebutton.api.messaging.messages.UserUnsharedWebcam;
import org.bigbluebutton.web.services.ExpiredMeetingCleanupTimerTask;
import org.bigbluebutton.web.services.KeepAliveService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
@ -357,6 +367,10 @@ public class MeetingService implements MessageListener {
return recs;
}
public Map<String, Recording> filterRecordingsByMetadata(Map<String, Recording> recordings, Map<String, String> metadataFilters) {
return recordingService.filterRecordingsByMetadata(recordings, metadataFilters);
}
public HashMap<String,Recording> reorderRecordings(ArrayList<Recording> olds){
HashMap<String,Recording> map= new HashMap<String, Recording>();
for (Recording r:olds) {
@ -621,6 +635,85 @@ public class MeetingService implements MessageListener {
log.warn("The meeting " + message.meetingId + " doesn't exist");
}
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);
log.info("User {} joined the voice conference in the meeting {}", user.getFullname(), message.meetingId);
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");
}
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);
log.info("User {} left the voice conference in the meeting {}", user.getFullname(), message.meetingId);
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");
}
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);
if (message.listenOnly) {
log.info("User {} started to listen only in the meeting {}", user.getFullname(), message.meetingId);
} else {
log.info("User {} stopped to listen only in the meeting {}", user.getFullname(), message.meetingId);
}
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");
}
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);
log.info("User {} started to stream {} to the meeting {}", user.getFullname(), message.stream, message.meetingId);
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");
}
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);
log.info("User {} stopped to stream {} to the meeting {}", user.getFullname(), message.stream, message.meetingId);
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() {
@ -639,6 +732,21 @@ public class MeetingService implements MessageListener {
userLeft((UserLeft)message);
} else if (message instanceof UserStatusChanged) {
updatedStatus((UserStatusChanged)message);
} else if (message instanceof UserJoinedVoice) {
log.info("Processing voice user joined message.");
userJoinedVoice((UserJoinedVoice)message);
} else if (message instanceof UserLeftVoice) {
log.info("Processing voice user left message.");
userLeftVoice((UserLeftVoice)message);
} else if (message instanceof UserListeningOnly) {
log.info("Processing user listening only message.");
userListeningOnly((UserListeningOnly)message);
} else if (message instanceof UserSharedWebcam) {
log.info("Processing user shared webcam message.");
userSharedWebcam((UserSharedWebcam)message);
} else if (message instanceof UserUnsharedWebcam) {
log.info("Processing user unshared webcam message.");
userUnsharedWebcam((UserUnsharedWebcam)message);
} else if (message instanceof RemoveExpiredMeetings) {
checkAndRemoveExpiredMeetings();
} else if (message instanceof CreateMeeting) {

View File

@ -23,6 +23,9 @@ import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.bigbluebutton.api.domain.Recording;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -75,6 +78,28 @@ public class RecordingService {
return recs;
}
public boolean recordingMatchesMetadata(Recording recording, Map<String, String> metadataFilters) {
for (Map.Entry<String, String> filter : metadataFilters.entrySet()) {
String metadataValue = recording.getMetadata().get(filter.getKey());
if (metadataValue != null && metadataValue.equals(filter.getValue())) {
// the recording has the metadata specified
// AND the value is the same as the filter
} else {
return false;
}
}
return true;
}
public Map<String, Recording> filterRecordingsByMetadata(Map<String, Recording> recordings, Map<String, String> metadataFilters) {
Map<String, Recording> resultRecordings = new HashMap<String, Recording>();
for (Map.Entry<String, Recording> entry : recordings.entrySet()) {
if (recordingMatchesMetadata(entry.getValue(), metadataFilters))
resultRecordings.put(entry.getKey(), entry.getValue());
}
return resultRecordings;
}
public boolean existAnyRecording(ArrayList<String> idList){
ArrayList<String> publishList=getAllRecordingIds(publishedDir);
ArrayList<String> unpublishList=getAllRecordingIds(unpublishedDir);

View File

@ -29,7 +29,6 @@ import java.util.concurrent.ConcurrentMap;
import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.bigbluebutton.api.MeetingService;
public class Meeting {
private static Logger log = LoggerFactory.getLogger(Meeting.class);
@ -316,6 +315,33 @@ public class Meeting {
private boolean hasEnded() {
return endTime > 0;
}
public int getNumListenOnly() {
int sum = 0;
for (String key : users.keySet()) {
User u = (User) users.get(key);
if (u.isListeningOnly()) sum++;
}
return sum;
}
public int getNumVoiceJoined() {
int sum = 0;
for (String key : users.keySet()) {
User u = (User) users.get(key);
if (u.isVoiceJoined()) sum++;
}
return sum;
}
public int getNumVideos() {
int sum = 0;
for (String key : users.keySet()) {
User u = (User) users.get(key);
sum += u.getStreams().size();
}
return sum;
}
public void addUserCustomData(String userID, Map<String, String> data) {
userCustomData.put(userID, data);

View File

@ -19,6 +19,9 @@
package org.bigbluebutton.api.domain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -28,6 +31,9 @@ public class User {
private String fullname;
private String role;
private Map<String,String> status;
private Boolean listeningOnly = false;
private Boolean voiceJoined = false;
private List<String> streams;
public User(String internalUserId, String externalUserId, String fullname, String role) {
this.internalUserId = internalUserId;
@ -35,6 +41,7 @@ public class User {
this.fullname = fullname;
this.role = role;
this.status = new ConcurrentHashMap<String, String>();
this.streams = Collections.synchronizedList(new ArrayList<String>());
}
public String getInternalUserId() {
@ -78,4 +85,44 @@ public class User {
public Map<String,String> getStatus(){
return this.status;
}
public boolean isPresenter() {
String isPresenter = this.status.get("presenter");
if (isPresenter != null) {
return isPresenter.equalsIgnoreCase("true");
}
return false;
}
public void addStream(String stream) {
streams.add(stream);
}
public void removeStream(String stream) {
streams.remove(stream);
}
public List<String> getStreams() {
return streams;
}
public Boolean hasVideo() {
return this.getStreams().size() > 0;
}
public Boolean isListeningOnly() {
return listeningOnly;
}
public void setListeningOnly(Boolean listeningOnly) {
this.listeningOnly = listeningOnly;
}
public Boolean isVoiceJoined() {
return voiceJoined;
}
public void setVoiceJoined(Boolean voiceJoined) {
this.voiceJoined = voiceJoined;
}
}

View File

@ -1,7 +1,5 @@
package org.bigbluebutton.api.messaging;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.bigbluebutton.api.messaging.messages.KeepAliveReply;
@ -9,14 +7,18 @@ import org.bigbluebutton.api.messaging.messages.MeetingDestroyed;
import org.bigbluebutton.api.messaging.messages.MeetingEnded;
import org.bigbluebutton.api.messaging.messages.MeetingStarted;
import org.bigbluebutton.api.messaging.messages.UserJoined;
import org.bigbluebutton.api.messaging.messages.UserJoinedVoice;
import org.bigbluebutton.api.messaging.messages.UserLeft;
import org.bigbluebutton.api.messaging.messages.UserLeftVoice;
import org.bigbluebutton.api.messaging.messages.UserListeningOnly;
import org.bigbluebutton.api.messaging.messages.UserSharedWebcam;
import org.bigbluebutton.api.messaging.messages.UserStatusChanged;
import org.bigbluebutton.api.messaging.messages.UserUnsharedWebcam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
public class MeetingMessageHandler implements MessageHandler {
private static Logger log = LoggerFactory.getLogger(MeetingMessageHandler.class);
@ -28,8 +30,6 @@ public class MeetingMessageHandler implements MessageHandler {
}
public void handleMessage(String pattern, String channel, String message) {
Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
@ -121,8 +121,51 @@ public class MeetingMessageHandler implements MessageHandler {
for (MessageListener listener : listeners) {
listener.handle(new UserLeft(meetingId, userid));
}
} else if (MessagingConstants.USER_JOINED_VOICE_EVENT.equalsIgnoreCase(messageName)) {
System.out.println("Handling [" + messageName + "] message.");
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)) {
System.out.println("Handling [" + messageName + "] message.");
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)) {
System.out.println("Handling [" + messageName + "] message.");
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)) {
System.out.println("Handling [" + messageName + "] message.");
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)) {
System.out.println("Handling [" + messageName + "] message.");
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));
}
}
}
}
}
}
}

View File

@ -47,7 +47,11 @@ public class MessagingConstants {
public static final String USER_JOINED_EVENT = "user_joined_message";
public static final String USER_LEFT_EVENT = "user_left_message";
public static final String USER_STATUS_CHANGE_EVENT = "user_status_changed_message";
public static final String USER_JOINED_VOICE_EVENT = "user_joined_voice_message";
public static final String USER_LEFT_VOICE_EVENT = "user_left_voice_message";
public static final String USER_LISTEN_ONLY_EVENT = "user_listening_only";
public static final String USER_SHARE_WEBCAM_EVENT = "user_shared_webcam_message";
public static final String USER_UNSHARE_WEBCAM_EVENT = "user_unshared_webcam_message";
public static final String SEND_POLLS_EVENT = "SendPollsEvent";
public static final String KEEP_ALIVE_REPLY = "keep_alive_reply";

View File

@ -0,0 +1,11 @@
package org.bigbluebutton.api.messaging.messages;
public class UserJoinedVoice implements IMessage {
public final String userId;
public final String meetingId;
public UserJoinedVoice(String meetingId, String userId) {
this.meetingId = meetingId;
this.userId = userId;
}
}

View File

@ -0,0 +1,11 @@
package org.bigbluebutton.api.messaging.messages;
public class UserLeftVoice implements IMessage {
public final String userId;
public final String meetingId;
public UserLeftVoice(String meetingId, String userId) {
this.meetingId = meetingId;
this.userId = userId;
}
}

View File

@ -0,0 +1,13 @@
package org.bigbluebutton.api.messaging.messages;
public class UserListeningOnly implements IMessage {
public final String userId;
public final String meetingId;
public final Boolean listenOnly;
public UserListeningOnly(String meetingId, String userId, Boolean listenOnly) {
this.meetingId = meetingId;
this.userId = userId;
this.listenOnly = listenOnly;
}
}

View File

@ -0,0 +1,13 @@
package org.bigbluebutton.api.messaging.messages;
public class UserSharedWebcam implements IMessage {
public final String userId;
public final String meetingId;
public final String stream;
public UserSharedWebcam(String meetingId, String userId, String stream) {
this.meetingId = meetingId;
this.userId = userId;
this.stream = stream;
}
}

View File

@ -0,0 +1,13 @@
package org.bigbluebutton.api.messaging.messages;
public class UserUnsharedWebcam implements IMessage {
public final String userId;
public final String meetingId;
public final String stream;
public UserUnsharedWebcam(String meetingId, String userId, String stream) {
this.meetingId = meetingId;
this.userId = userId;
this.stream = stream;
}
}