merge remove-bbb-commons, working prototype, need to add status method to listener
This commit is contained in:
commit
2ac6aaa09a
3
bbb-video/.gitignore
vendored
3
bbb-video/.gitignore
vendored
@ -1 +1,4 @@
|
||||
bin
|
||||
build
|
||||
dist
|
||||
lib
|
||||
|
@ -57,7 +57,7 @@ repositories {
|
||||
}
|
||||
}
|
||||
mavenRepo urls: 'http://scala-tools.org/repo-releases/'
|
||||
flatDir name: 'fileRepo', dirs: System.getenv()['FLAT_REPO']
|
||||
//flatDir name: 'fileRepo', dirs: System.getenv()['FLAT_REPO']
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -113,7 +113,7 @@ dependencies {
|
||||
compile 'redis.clients:jedis:1.5.1'
|
||||
compile 'commons-pool:commons-pool:1.5.5'
|
||||
|
||||
compile 'org/bigbluebutton/common:bbb-common-message:0.8@jar'
|
||||
//compile 'org/bigbluebutton/common:bbb-common-message:0.8@jar'
|
||||
|
||||
// Freeswitch ESL Client
|
||||
compile 'org/freeswitch:fs-esl-client:0.8.1@jar'
|
||||
|
@ -16,23 +16,14 @@
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.bigbluebutton.conference;
|
||||
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
public interface IRoomListener {
|
||||
public String getName();
|
||||
public void participantStatusChange(Long userid, String status, Object value);
|
||||
public void participantJoined(Participant participant);
|
||||
public void participantLeft(Long userid);
|
||||
|
||||
/*
|
||||
* TODO: perhaps this should actually be merged with IRoomListener
|
||||
* in some way, but for now I am using it to test the Spring Integration / JMS
|
||||
* stuff. (JRT - 09/26/2009)
|
||||
*/
|
||||
public interface IConferenceEventListener {
|
||||
|
||||
@Gateway(requestChannel="conferenceStarted")
|
||||
void started(Room room);
|
||||
|
||||
@Gateway(requestChannel="conferenceEnded")
|
||||
void ended(Room room);
|
||||
|
||||
@Gateway(requestChannel="participantsUpdated")
|
||||
void participantsUpdated(Room room);
|
||||
public void endAndKickAll();
|
||||
}
|
118
bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Participant.java
Executable file
118
bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Participant.java
Executable file
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2010 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 2.1 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.bigbluebutton.conference;
|
||||
|
||||
import net.jcip.annotations.ThreadSafe;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.io.Serializable;
|
||||
import java.lang.Long;
|
||||
/**
|
||||
* Contains information for a Participant. Encapsulates status and the
|
||||
* only way to change/add status is through setStatus;
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class Participant implements Serializable {
|
||||
private Long userid;
|
||||
private String name;
|
||||
private String role = "VIEWER";
|
||||
private String externUserID;
|
||||
|
||||
private final Map status;
|
||||
private Map<String, Object> unmodifiableStatus;
|
||||
|
||||
public Participant(Long userid, String name, String role, String externUserID, Map<String, Object> status) {
|
||||
this.userid = userid;
|
||||
this.name = name;
|
||||
this.role = role;
|
||||
this.externUserID = externUserID;
|
||||
this.status = new ConcurrentHashMap<String, Object>(status);
|
||||
unmodifiableStatus = Collections.unmodifiableMap(status);
|
||||
}
|
||||
|
||||
public boolean isModerator() {
|
||||
return "MODERATOR".equals(role);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Long getUserid() {
|
||||
return userid;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public String getExternUserID() {
|
||||
return externUserID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns that status for this participant. However, the status cannot
|
||||
* be modified. To do that, setStatus(...) must be used.
|
||||
*/
|
||||
public Map getStatus() {
|
||||
return unmodifiableStatus;
|
||||
}
|
||||
|
||||
public void setStatus(String statusName, Object value) {
|
||||
// Should we sychronize?
|
||||
synchronized (this) {
|
||||
status.put(statusName, value);
|
||||
/**
|
||||
* Update unmodifiableStatus as it does not get synched with status.
|
||||
* Not sure it it should auto-syc, so just sync it.
|
||||
* Not sure if this is the right way to do it (ralam 2/26/2009).
|
||||
*/
|
||||
unmodifiableStatus = Collections.unmodifiableMap(status);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeStatus(String statusName) {
|
||||
// Should we sychronize?
|
||||
synchronized (this) {
|
||||
status.remove(statusName);
|
||||
/**
|
||||
* Update unmodifiableStatus as it does not get synched with status.
|
||||
* Not sure it it should auto-syc, so just sync it.
|
||||
* Not sure if this is the right way to do it (ralam 2/26/2009).
|
||||
*/
|
||||
unmodifiableStatus = Collections.unmodifiableMap(status);
|
||||
}
|
||||
}
|
||||
|
||||
public Map toMap() {
|
||||
Map m = new HashMap();
|
||||
m.put("userid", userid);
|
||||
m.put("name", name);
|
||||
m.put("role", role);
|
||||
/**
|
||||
* Create a copy of the status instead of returning the
|
||||
* unmodifiableMap. This way callers can still manipulate it
|
||||
* for their own purpose but our copy still remains unmodified.
|
||||
*/
|
||||
m.put("status", new HashMap(unmodifiableStatus));
|
||||
return m;
|
||||
}
|
||||
}
|
@ -19,48 +19,57 @@
|
||||
|
||||
package org.bigbluebutton.conference;
|
||||
|
||||
import org.bigbluebutton.conference.service.recorder.pubsub.RedisPublisher;
|
||||
import org.bigbluebutton.conference.service.messaging.RedisPublisher;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
|
||||
public class ParticipantUpdatingRoomListener implements IRoomListener{
|
||||
|
||||
RedisPublisher publisher;
|
||||
private IConferenceEventListener conferenceEventListener;
|
||||
private Room room;
|
||||
private static Logger log = Red5LoggerFactory.getLogger(ParticipantUpdatingRoomListener.class, "bigbluebutton");
|
||||
|
||||
public ParticipantUpdatingRoomListener(IConferenceEventListener lstnr, Room room, RedisPublisher publisher) {
|
||||
this.conferenceEventListener = lstnr;
|
||||
RedisPublisher publisher;
|
||||
//private IConferenceEventListener conferenceEventListener;
|
||||
private Room room;
|
||||
private final String pubsub_pattern;
|
||||
|
||||
public ParticipantUpdatingRoomListener(Room room, RedisPublisher publisher) {
|
||||
//this.conferenceEventListener = lstnr;
|
||||
this.room = room;
|
||||
this.publisher=publisher;
|
||||
this.pubsub_pattern="bigbluebutton:meeting:participants";
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "TEMPNAME";
|
||||
return "PARTICIPANT:UPDATE:ROOM";
|
||||
}
|
||||
|
||||
public void participantStatusChange(Long userid, String status, Object value){
|
||||
if (conferenceEventListener != null) {
|
||||
conferenceEventListener.participantsUpdated(room);
|
||||
if (publisher != null) {
|
||||
//conferenceEventListener.participantsUpdated(room);
|
||||
//redis pubsub
|
||||
publisher.publish(this.pubsub_pattern, this.room.getName()+":status:"+userid+":"+status+":"+value);
|
||||
log.debug("Publishing message to {} action status change",this.pubsub_pattern);
|
||||
}
|
||||
}
|
||||
|
||||
public void participantJoined(Participant p) {
|
||||
if (conferenceEventListener != null) {
|
||||
conferenceEventListener.participantsUpdated(room);
|
||||
if (publisher != null) {
|
||||
//conferenceEventListener.participantsUpdated(room);
|
||||
//redis pubsub
|
||||
//redis pubsub test
|
||||
publisher.publish("bigbluebutton:conference:join", room.getName()+":"+p.getUserid()+":"+p.getName()+":"+p.getRole());
|
||||
|
||||
publisher.publish(this.pubsub_pattern,this.room.getName()+":join:"+p.getUserid()+":"+p.getName()+":"+p.getRole());
|
||||
log.debug("Publishing message to {} action join",this.pubsub_pattern);
|
||||
}
|
||||
}
|
||||
|
||||
public void participantLeft(Long userid) {
|
||||
if (conferenceEventListener != null) {
|
||||
conferenceEventListener.participantsUpdated(room);
|
||||
if (publisher != null) {
|
||||
//conferenceEventListener.participantsUpdated(room);
|
||||
//redis pubsub
|
||||
//redis pubsub test
|
||||
publisher.publish("bigbluebutton:conference:remove", room.getName()+":"+userid);
|
||||
publisher.publish(this.pubsub_pattern, this.room.getName()+":left:"+userid);
|
||||
log.debug("Publishing message to {} action left",this.pubsub_pattern);
|
||||
}
|
||||
}
|
||||
|
||||
|
158
bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Room.java
Executable file
158
bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Room.java
Executable file
@ -0,0 +1,158 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2010 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 2.1 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.bigbluebutton.conference;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import net.jcip.annotations.ThreadSafe;
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
/**
|
||||
* Contains information about a Room and it's Participants.
|
||||
* Encapsulates Participants and RoomListeners.
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class Room implements Serializable {
|
||||
private static Logger log = Red5LoggerFactory.getLogger( Room.class, "bigbluebutton" );
|
||||
|
||||
private String name;
|
||||
private Map <Long, Participant> participants;
|
||||
|
||||
// these should stay transient so they're not serialized in ActiveMQ messages:
|
||||
//private transient Map <Long, Participant> unmodifiableMap;
|
||||
private transient final Map<String, IRoomListener> listeners;
|
||||
|
||||
public Room(String name) {
|
||||
this.name = name;
|
||||
participants = new ConcurrentHashMap<Long, Participant>();
|
||||
//unmodifiableMap = Collections.unmodifiableMap(participants);
|
||||
listeners = new ConcurrentHashMap<String, IRoomListener>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void addRoomListener(IRoomListener listener) {
|
||||
if (! listeners.containsKey(listener.getName())) {
|
||||
log.debug("adding room listener");
|
||||
listeners.put(listener.getName(), listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeRoomListener(IRoomListener listener) {
|
||||
log.debug("removing room listener");
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void addParticipant(Participant participant) {
|
||||
synchronized (this) {
|
||||
log.debug("adding participant {}",participant.getUserid());
|
||||
participants.put(participant.getUserid(), participant);
|
||||
// unmodifiableMap = Collections.unmodifiableMap(participants)
|
||||
}
|
||||
log.debug("addparticipant - informing roomlisteners {}",listeners.size());
|
||||
for (Iterator it = listeners.values().iterator(); it.hasNext();) {
|
||||
//for (IRoomListener listener : listeners) {
|
||||
log.debug("calling participantJoined on listener");
|
||||
IRoomListener listener = (IRoomListener) it.next();
|
||||
log.debug("calling participantJoined on listener {}",listener.getName());
|
||||
listener.participantJoined(participant);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeParticipant(Long userid) {
|
||||
boolean present = false;
|
||||
synchronized (this) {
|
||||
present = participants.containsKey(userid);
|
||||
if (present) {
|
||||
log.debug("removing participant");
|
||||
participants.remove(userid);
|
||||
}
|
||||
}
|
||||
if (present) {
|
||||
for (Iterator it = listeners.values().iterator(); it.hasNext();) {
|
||||
log.debug("calling participantLeft on listener");
|
||||
IRoomListener listener = (IRoomListener) it.next();
|
||||
log.debug("calling participantLeft on listener {}",listener.getName());
|
||||
listener.participantLeft(userid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void changeParticipantStatus(Long userid, String status, Object value) {
|
||||
boolean present = false;
|
||||
synchronized (this) {
|
||||
present = participants.containsKey(userid);
|
||||
if (present) {
|
||||
log.debug("change participant status");
|
||||
Participant p = participants.get(userid);
|
||||
p.setStatus(status, value);
|
||||
//participants.put(userid, p);
|
||||
//unmodifiableMap = Collections.unmodifiableMap(participants);
|
||||
}
|
||||
}
|
||||
if (present) {
|
||||
for (Iterator it = listeners.values().iterator(); it.hasNext();) {
|
||||
log.debug("calling participantStatusChange on listener");
|
||||
IRoomListener listener = (IRoomListener) it.next();
|
||||
log.debug("calling participantStatusChange on listener {}",listener.getName());
|
||||
listener.participantStatusChange(userid, status, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void endAndKickAll() {
|
||||
for (Iterator it = listeners.values().iterator(); it.hasNext();) {
|
||||
IRoomListener listener = (IRoomListener) it.next();
|
||||
log.debug("calling endAndKickAll on listener {}",listener.getName());
|
||||
listener.endAndKickAll();
|
||||
}
|
||||
}
|
||||
|
||||
public Map getParticipants() {
|
||||
return participants;//unmodifiableMap;
|
||||
}
|
||||
|
||||
public Collection<Participant> getParticipantCollection() {
|
||||
return participants.values();
|
||||
}
|
||||
|
||||
public int getNumberOfParticipants() {
|
||||
log.debug("Returning number of participants: " + participants.size());
|
||||
return participants.size();
|
||||
}
|
||||
|
||||
public int getNumberOfModerators() {
|
||||
int sum = 0;
|
||||
for (Iterator<Participant> it = participants.values().iterator(); it.hasNext(); ) {
|
||||
Participant part = it.next();
|
||||
if (part.isModerator()) {
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
log.debug("Returning number of moderators: " + sum);
|
||||
return sum;
|
||||
}
|
||||
|
||||
}
|
@ -19,8 +19,8 @@
|
||||
package org.bigbluebutton.conference;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.bigbluebutton.conference.service.messaging.RedisPublisher;
|
||||
import org.bigbluebutton.conference.service.recorder.RedisDispatcher;
|
||||
import org.bigbluebutton.conference.service.recorder.pubsub.RedisPublisher;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import net.jcip.annotations.ThreadSafe;
|
||||
import java.util.Map;
|
||||
@ -35,11 +35,9 @@ public class RoomsManager {
|
||||
|
||||
private final Map <String, Room> rooms;
|
||||
|
||||
private IConferenceEventListener conferenceEventListener;
|
||||
//replaced with redis publisher
|
||||
//private IConferenceEventListener conferenceEventListener;
|
||||
|
||||
|
||||
|
||||
/*redis pubsub*/
|
||||
RedisPublisher publisher;
|
||||
|
||||
public RoomsManager() {
|
||||
@ -47,14 +45,14 @@ public class RoomsManager {
|
||||
|
||||
}
|
||||
|
||||
public void addRoom(final Room room) {
|
||||
public void addRoom(Room room) {
|
||||
log.debug("Adding room {}", room.getName());
|
||||
room.addRoomListener(new ParticipantUpdatingRoomListener(conferenceEventListener, room,publisher));
|
||||
room.addRoomListener(new ParticipantUpdatingRoomListener(room,publisher));
|
||||
|
||||
if (checkEvtListener()) {
|
||||
conferenceEventListener.started(room);
|
||||
if (checkPublisher()) {
|
||||
//conferenceEventListener.started(room);
|
||||
//redis pubsub test
|
||||
publisher.publish("bigbluebutton:conference:status", room.getName()+":started");
|
||||
publisher.publish("bigbluebutton:meeting:state", room.getName()+":started");
|
||||
|
||||
log.debug("Notified event listener of conference start");
|
||||
}
|
||||
@ -64,12 +62,12 @@ public class RoomsManager {
|
||||
public void removeRoom(String name) {
|
||||
log.debug("Remove room {}", name);
|
||||
Room room = rooms.remove(name);
|
||||
if (checkEvtListener() && room != null) {
|
||||
if (checkPublisher() && room != null) {
|
||||
room.endAndKickAll();
|
||||
conferenceEventListener.ended(room);
|
||||
//conferenceEventListener.ended(room);
|
||||
|
||||
//redis pubsub test
|
||||
publisher.publish("bigbluebutton:conference:status", room.getName()+":ended");
|
||||
publisher.publish("bigbluebutton:meeting:state",room.getName()+":ended");
|
||||
|
||||
log.debug("Notified event listener of conference end");
|
||||
}
|
||||
@ -82,8 +80,8 @@ public class RoomsManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkEvtListener() {
|
||||
return conferenceEventListener != null;
|
||||
private boolean checkPublisher() {
|
||||
return publisher != null;
|
||||
}
|
||||
|
||||
|
||||
@ -96,8 +94,8 @@ public class RoomsManager {
|
||||
}
|
||||
|
||||
// this method is called by incoming JMS requests (Spring integration)
|
||||
public void endMeetingRequest(Room room) {
|
||||
room = getRoom(room.getName()); // must do this because the room coming in is serialized (no transient values are present)
|
||||
public void endMeetingRequest(String roomname) {
|
||||
Room room = getRoom(roomname); // must do this because the room coming in is serialized (no transient values are present)
|
||||
log.debug("End meeting request for room: {} ", room.getName());
|
||||
room.endAndKickAll();
|
||||
}
|
||||
@ -144,19 +142,20 @@ public class RoomsManager {
|
||||
log.debug("Add participant {}", participant.getName());
|
||||
Room r = getRoom(roomName);
|
||||
if (r != null) {
|
||||
if (checkEvtListener()) {
|
||||
conferenceEventListener.participantsUpdated(r);
|
||||
if (checkPublisher()) {
|
||||
//conferenceEventListener.participantsUpdated(r);
|
||||
//missing_method()
|
||||
if (r.getNumberOfParticipants() == 0) {
|
||||
conferenceEventListener.started(r);
|
||||
//conferenceEventListener.started(r);
|
||||
log.debug("Notified event listener of conference start");
|
||||
//redis pubsub test
|
||||
publisher.publish("bigbluebutton:conference:status", r.getName()+":started");
|
||||
publisher.publish("bigbluebutton:meeting:state", roomName+":started");
|
||||
|
||||
}
|
||||
}
|
||||
r.addParticipant(participant);
|
||||
//redis pubsub test
|
||||
publisher.publish("bigbluebutton:conference:join", r.getName()+":"+participant.getUserid()+":"+participant.getName()+":"+participant.getRole());
|
||||
//publisher.publish("bigbluebutton:conference:join", r.getName()+":"+participant.getUserid()+":"+participant.getName()+":"+participant.getRole());
|
||||
|
||||
return;
|
||||
}
|
||||
@ -167,14 +166,11 @@ public class RoomsManager {
|
||||
log.debug("Remove participant {} from {}", userid, roomName);
|
||||
Room r = getRoom(roomName);
|
||||
if (r != null) {
|
||||
if (checkEvtListener()) {
|
||||
conferenceEventListener.participantsUpdated(r);
|
||||
if (checkPublisher()) {
|
||||
//conferenceEventListener.participantsUpdated(r);
|
||||
//missing method()?
|
||||
}
|
||||
r.removeParticipant(userid);
|
||||
//redis pubsub test
|
||||
|
||||
publisher.publish("bigbluebutton:conference:remove", r.getName()+":"+userid);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
@ -191,13 +187,13 @@ public class RoomsManager {
|
||||
log.warn("Changing participant status on a non-existing room {}", roomName);
|
||||
}
|
||||
|
||||
public void setConferenceEventListener(IConferenceEventListener conferenceEventListener) {
|
||||
this.conferenceEventListener = conferenceEventListener;
|
||||
}
|
||||
|
||||
public IConferenceEventListener getConferenceEventListener() {
|
||||
return conferenceEventListener;
|
||||
}
|
||||
// public void setConferenceEventListener(IConferenceEventListener conferenceEventListener) {
|
||||
// this.conferenceEventListener = conferenceEventListener;
|
||||
// }
|
||||
//
|
||||
// public IConferenceEventListener getConferenceEventListener() {
|
||||
// return conferenceEventListener;
|
||||
// }
|
||||
|
||||
public RedisPublisher getPublisher() {
|
||||
return publisher;
|
||||
|
@ -0,0 +1,132 @@
|
||||
package org.bigbluebutton.conference.service.messaging;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bigbluebutton.conference.RoomsManager;
|
||||
import org.bigbluebutton.conference.service.presentation.ConversionUpdatesMessageListener;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
|
||||
|
||||
public class RedisListener{
|
||||
|
||||
JedisPool redisPool;
|
||||
RoomsManager roomsManager;
|
||||
ConversionUpdatesMessageListener messageListener;
|
||||
|
||||
public RedisListener() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void init(){
|
||||
Jedis jedis = redisPool.getResource();
|
||||
//subscribe(jedis);
|
||||
redisPool.returnResource(jedis);
|
||||
}
|
||||
|
||||
public void subscribe(final Jedis jedis){
|
||||
Thread t= new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
jedis.subscribe(new JedisPubSub() {
|
||||
|
||||
@Override
|
||||
public void onUnsubscribe(String arg0, int arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscribe(String arg0, int arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPUnsubscribe(String arg0, int arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPSubscribe(String arg0, int arg1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPMessage(String pattern, String channel, String message) {
|
||||
if(channel.equalsIgnoreCase("bigbluebutton:meeting:request")){
|
||||
String[] args=message.split(":");
|
||||
String roomname=args[0];
|
||||
String type=args[1];
|
||||
|
||||
if(type.equalsIgnoreCase("end")){
|
||||
roomsManager.endMeetingRequest(roomname);
|
||||
}
|
||||
}
|
||||
else if(channel.equalsIgnoreCase("bigbluebutton:meeting:presentation")){
|
||||
String[] args=message.split(":");
|
||||
|
||||
HashMap<String,Object> map=new HashMap<String, Object>();
|
||||
map.put("code",args[0]);
|
||||
map.put("presentationName",args[1]);
|
||||
map.put("conference",args[2]);
|
||||
|
||||
String messageKey=args[3];
|
||||
map.put("messageKey",messageKey);
|
||||
|
||||
if(messageKey.equalsIgnoreCase(ConversionUpdatesMessageListener.PAGE_COUNT_EXCEEDED_KEY)){
|
||||
map.put("numberOfPages", args[4]);
|
||||
map.put("maxNumberPages", args[5]);
|
||||
}
|
||||
else if(messageKey.equalsIgnoreCase(ConversionUpdatesMessageListener.GENERATED_SLIDE_KEY)){
|
||||
map.put("numberOfPages", args[4]);
|
||||
map.put("pagesCompleted", args[5]);
|
||||
}
|
||||
else if(messageKey.equalsIgnoreCase(ConversionUpdatesMessageListener.CONVERSION_COMPLETED_KEY)){
|
||||
map.put("slidesInfo", args[4]);
|
||||
}
|
||||
|
||||
messageListener.handleReceivedMessage(map);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String channel, String message) {
|
||||
|
||||
}
|
||||
}, "bigbluebutton:meeting:*");
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
|
||||
public JedisPool getRedisPool() {
|
||||
return redisPool;
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool) {
|
||||
this.redisPool = redisPool;
|
||||
}
|
||||
|
||||
public RoomsManager getRoomsManager() {
|
||||
return roomsManager;
|
||||
}
|
||||
|
||||
public void setRoomsManager(RoomsManager roomsManager) {
|
||||
this.roomsManager = roomsManager;
|
||||
}
|
||||
|
||||
public ConversionUpdatesMessageListener getMessageListener() {
|
||||
return messageListener;
|
||||
}
|
||||
|
||||
public void setMessageListener(ConversionUpdatesMessageListener messageListener) {
|
||||
this.messageListener = messageListener;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package org.bigbluebutton.conference.service.messaging;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
|
||||
public class RedisPublisher{
|
||||
|
||||
JedisPool redisPool;
|
||||
|
||||
public RedisPublisher(){
|
||||
super();
|
||||
}
|
||||
|
||||
public void publish(String channel, String message){
|
||||
Jedis jedis = redisPool.getResource();
|
||||
try {
|
||||
jedis.publish(channel, message);
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
}
|
||||
}
|
||||
|
||||
public JedisPool getRedisPool() {
|
||||
return redisPool;
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool) {
|
||||
this.redisPool = redisPool;
|
||||
}
|
||||
|
||||
}
|
@ -29,9 +29,12 @@ public class ParticipantsApplication {
|
||||
private RoomsManager roomsManager;
|
||||
|
||||
public boolean createRoom(String name) {
|
||||
log.info("Creating room {}", name);
|
||||
roomsManager.addRoom(new Room(name));
|
||||
return true;
|
||||
if(!roomsManager.hasRoom(name)){
|
||||
log.info("Creating room {}", name);
|
||||
roomsManager.addRoom(new Room(name));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean destroyRoom(String name) {
|
||||
@ -68,7 +71,7 @@ public class ParticipantsApplication {
|
||||
public Map getParticipants(String roomName) {
|
||||
log.debug("getParticipants - " + roomName);
|
||||
if (! roomsManager.hasRoom(roomName)) {
|
||||
log.warn("Could not find room "+roomName);
|
||||
log.warn("Could not find room "+roomName+" Total rooms "+roomsManager.numberOfRooms());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,11 @@ public class ParticipantsService {
|
||||
Map participants = new HashMap();
|
||||
if (p == null) {
|
||||
participants.put("count", 0);
|
||||
log.debug("partipants of {} is null",roomName);
|
||||
} else {
|
||||
|
||||
participants.put("count", p.size());
|
||||
log.debug("number of partipants is {}",p.size());
|
||||
if (p.size() > 0) {
|
||||
/**
|
||||
* Somehow we need to convert to Map so the client will be
|
||||
|
@ -21,53 +21,49 @@
|
||||
*/
|
||||
package org.bigbluebutton.conference.service.presentation;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.MapMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConversionUpdatesMessageListener implements MessageListener{
|
||||
public class ConversionUpdatesMessageListener {
|
||||
private static Logger log = Red5LoggerFactory.getLogger(ConversionUpdatesMessageListener.class, "bigbluebutton");
|
||||
|
||||
private ConversionUpdatesProcessor conversionUpdatesProcessor;
|
||||
|
||||
private static final String OFFICE_DOC_CONVERSION_SUCCESS_KEY = "OFFICE_DOC_CONVERSION_SUCCESS";
|
||||
private static final String OFFICE_DOC_CONVERSION_FAILED_KEY = "OFFICE_DOC_CONVERSION_FAILED";
|
||||
private static final String SUPPORTED_DOCUMENT_KEY = "SUPPORTED_DOCUMENT";
|
||||
private static final String UNSUPPORTED_DOCUMENT_KEY = "UNSUPPORTED_DOCUMENT";
|
||||
private static final String PAGE_COUNT_FAILED_KEY = "PAGE_COUNT_FAILED";
|
||||
private static final String PAGE_COUNT_EXCEEDED_KEY = "PAGE_COUNT_EXCEEDED";
|
||||
private static final String GENERATED_SLIDE_KEY = "GENERATED_SLIDE";
|
||||
private static final String GENERATING_THUMBNAIL_KEY = "GENERATING_THUMBNAIL";
|
||||
private static final String GENERATED_THUMBNAIL_KEY = "GENERATED_THUMBNAIL";
|
||||
private static final String CONVERSION_COMPLETED_KEY = "CONVERSION_COMPLETED";
|
||||
public static final String OFFICE_DOC_CONVERSION_SUCCESS_KEY = "OFFICE_DOC_CONVERSION_SUCCESS";
|
||||
public static final String OFFICE_DOC_CONVERSION_FAILED_KEY = "OFFICE_DOC_CONVERSION_FAILED";
|
||||
public static final String SUPPORTED_DOCUMENT_KEY = "SUPPORTED_DOCUMENT";
|
||||
public static final String UNSUPPORTED_DOCUMENT_KEY = "UNSUPPORTED_DOCUMENT";
|
||||
public static final String PAGE_COUNT_FAILED_KEY = "PAGE_COUNT_FAILED";
|
||||
public static final String PAGE_COUNT_EXCEEDED_KEY = "PAGE_COUNT_EXCEEDED";
|
||||
public static final String GENERATED_SLIDE_KEY = "GENERATED_SLIDE";
|
||||
public static final String GENERATING_THUMBNAIL_KEY = "GENERATING_THUMBNAIL";
|
||||
public static final String GENERATED_THUMBNAIL_KEY = "GENERATED_THUMBNAIL";
|
||||
public static final String CONVERSION_COMPLETED_KEY = "CONVERSION_COMPLETED";
|
||||
|
||||
public void start() {
|
||||
log.debug("Starting conversion updates receiver.");
|
||||
conversionUpdatesProcessor.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public void onMessage(Message jmsMessage){
|
||||
if (jmsMessage instanceof MapMessage) {
|
||||
MapMessage mapMessage = ((MapMessage) jmsMessage);
|
||||
handleReceivedMessage(mapMessage);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void handleReceivedMessage(MapMessage mapMessage) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void handleReceivedMessage(Map mapMessage) {
|
||||
try{
|
||||
String code = mapMessage.getString("returnCode");
|
||||
String room = mapMessage.getString("room");
|
||||
String presentationName = mapMessage.getString("presentationName");
|
||||
String conference = mapMessage.getString("conference");
|
||||
String messageKey = mapMessage.getString("messageKey");
|
||||
String code = (String) mapMessage.get("returnCode");
|
||||
String room = (String) mapMessage.get("room");
|
||||
String presentationName = (String) mapMessage.get("presentationName");
|
||||
String conference = (String) mapMessage.get("conference");
|
||||
String messageKey = (String) mapMessage.get("messageKey");
|
||||
|
||||
Map message = new HashMap();
|
||||
message.put("conference", conference);
|
||||
@ -90,15 +86,15 @@ public class ConversionUpdatesMessageListener implements MessageListener{
|
||||
}
|
||||
else if(messageKey.equalsIgnoreCase(PAGE_COUNT_EXCEEDED_KEY)){
|
||||
log.debug("JMS: {}[{}]",messageKey,presentationName);
|
||||
int numberOfPages = mapMessage.getInt("numberOfPages");
|
||||
int maxNumberPages = mapMessage.getInt("maxNumberPages");
|
||||
int numberOfPages = (Integer) mapMessage.get("numberOfPages");
|
||||
int maxNumberPages = (Integer) mapMessage.get("maxNumberPages");
|
||||
message.put("numberOfPages", numberOfPages);
|
||||
message.put("maxNumberPages", maxNumberPages);
|
||||
conversionUpdatesProcessor.process(message);
|
||||
}
|
||||
else if(messageKey.equalsIgnoreCase(GENERATED_SLIDE_KEY)){
|
||||
int numberOfPages = mapMessage.getInt("numberOfPages");
|
||||
int pagesCompleted = mapMessage.getInt("pagesCompleted");
|
||||
int numberOfPages = (Integer) mapMessage.get("numberOfPages");
|
||||
int pagesCompleted = (Integer) mapMessage.get("pagesCompleted");
|
||||
message.put("numberOfPages", numberOfPages);
|
||||
message.put("pagesCompleted", pagesCompleted);
|
||||
|
||||
@ -106,7 +102,7 @@ public class ConversionUpdatesMessageListener implements MessageListener{
|
||||
conversionUpdatesProcessor.process(message);
|
||||
}
|
||||
else if(messageKey.equalsIgnoreCase(CONVERSION_COMPLETED_KEY)){
|
||||
String slidesInfo = mapMessage.getString("slidesInfo");
|
||||
String slidesInfo = (String) mapMessage.get("slidesInfo");
|
||||
message.put("slidesInfo", slidesInfo);
|
||||
log.debug("JMS: {}[{}]",messageKey,presentationName);
|
||||
conversionUpdatesProcessor.process(message);
|
||||
@ -114,7 +110,7 @@ public class ConversionUpdatesMessageListener implements MessageListener{
|
||||
else{
|
||||
log.error("Cannot handle recieved message.");
|
||||
}
|
||||
}catch(JMSException ex){
|
||||
}catch(Exception ex){
|
||||
log.warn(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ package org.bigbluebutton.conference.service.recorder;
|
||||
public interface Recorder {
|
||||
/**
|
||||
* Receive the messages from the bigbluebutton modules and send
|
||||
* them to a JMS queue. These messages are the events generated in a conference.
|
||||
* them to a queue. These messages are the events generated in a conference.
|
||||
* @param message a JSON String message with the attributes of an event
|
||||
*/
|
||||
public void record(String session, RecordEvent event);
|
||||
|
@ -1,94 +0,0 @@
|
||||
/**
|
||||
* ===License Header===
|
||||
*
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2010 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 2.1 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ===License Header===
|
||||
*/
|
||||
package org.bigbluebutton.conference.service.recorder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.Session;
|
||||
import org.bigbluebutton.recorder.EventMessage;
|
||||
import org.bigbluebutton.recorder.IEventMessage;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.core.MessageCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* The RecorderEventDispatcher class creates a object message and implements
|
||||
* the sender method for sending events to the JMS queue
|
||||
*
|
||||
**/
|
||||
public class RecorderEventDispatcher implements Recorder {
|
||||
private static Logger log = Red5LoggerFactory.getLogger( RecorderEventDispatcher.class, "bigbluebutton" );
|
||||
|
||||
private JmsTemplate jmsTemplate;
|
||||
|
||||
/**
|
||||
* RecorderEventDispatcher constructor.
|
||||
* @param conference the conference name
|
||||
* @param room the room name
|
||||
* @return RecorderEventDispatcher
|
||||
*/
|
||||
public RecorderEventDispatcher() {
|
||||
log.debug("create an instance of RecorderEventDispatcher");
|
||||
}
|
||||
|
||||
/**
|
||||
* The method creates a object message for sending to the jms queue.
|
||||
* @param event receive a IEventMessage object from bbb-common-messages
|
||||
*/
|
||||
public void sendEvents(final IEventMessage event) {
|
||||
jmsTemplate.send(new MessageCreator() {
|
||||
public Message createMessage(Session sn) throws JMSException {
|
||||
Message msg = sn.createObjectMessage(event);
|
||||
return msg;
|
||||
}
|
||||
});
|
||||
log.debug("create and send object message");
|
||||
}
|
||||
|
||||
/**
|
||||
* The method implements recordEvent from IRecoder. It sets the EventMessage
|
||||
* from bbb-common-messages with the room name, timestamp and message-event.
|
||||
* @param message this is a event-message sent by the BigBlueButton modules.
|
||||
* @see Recorder
|
||||
*/
|
||||
@Override
|
||||
public void record(String session, RecordEvent message) {
|
||||
EventMessage event = new EventMessage();
|
||||
event.setConferenceID(session);
|
||||
//event.setMessage(message);
|
||||
event.setTimeStamp(System.currentTimeMillis());
|
||||
sendEvents(event);
|
||||
log.debug("event-message: {}",message);
|
||||
}
|
||||
|
||||
/**
|
||||
* The method sets a Jms Template.
|
||||
* @param jmsTemplate a JmsTemplate.
|
||||
*/
|
||||
public void setJmsTemplate(JmsTemplate jmsTemplate){
|
||||
this.jmsTemplate=jmsTemplate;
|
||||
log.debug("set jms template");
|
||||
}
|
||||
}
|
@ -8,29 +8,25 @@ import redis.clients.jedis.JedisPool;
|
||||
|
||||
public class RedisDispatcher implements Recorder {
|
||||
private static final String COLON=":";
|
||||
private String host;
|
||||
private int port;
|
||||
JedisPool redisPool;
|
||||
|
||||
private Jedis jedis;
|
||||
|
||||
|
||||
// Jedis jedis;
|
||||
JedisPool jpool;
|
||||
public RedisDispatcher(String host, int port){
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
// jedis = new Jedis(host, port);
|
||||
// Config poolConfig = new Config();
|
||||
// jpool = new JedisPool(poolConfig, host, port);
|
||||
public RedisDispatcher(){
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void record(String session, RecordEvent message) {
|
||||
Jedis jedis = new Jedis(host, port);
|
||||
Long msgid = jedis.incr("global:nextRecordedMsgId");
|
||||
jedis.hmset("recording" + COLON + session + COLON + msgid, message.toMap());
|
||||
jedis.rpush("meeting" + COLON + session + COLON + "recordings", msgid.toString());
|
||||
|
||||
Jedis jedis = redisPool.getResource();
|
||||
try {
|
||||
Long msgid = jedis.incr("global:nextRecordedMsgId");
|
||||
jedis.hmset("recording" + COLON + session + COLON + msgid, message.toMap());
|
||||
jedis.rpush("meeting" + COLON + session + COLON + "recordings", msgid.toString());
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
}
|
||||
|
||||
//pool.destroy();
|
||||
}
|
||||
/*
|
||||
@Override
|
||||
@ -58,8 +54,13 @@ public class RedisDispatcher implements Recorder {
|
||||
}
|
||||
*/
|
||||
|
||||
public Jedis getJedis(){
|
||||
return jedis;
|
||||
public JedisPool getRedisPool() {
|
||||
return redisPool;
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool) {
|
||||
this.redisPool = redisPool;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
package org.bigbluebutton.conference.service.recorder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
public class RedisServer {
|
||||
protected Jedis jedis;
|
||||
|
||||
public RedisServer(String server, int port) {
|
||||
jedis = new Jedis(server, port,0);
|
||||
jedis.set("foo", "bar");
|
||||
}
|
||||
|
||||
public Jedis getJedis(){
|
||||
return jedis;
|
||||
}
|
||||
|
||||
public void closeConnection(){
|
||||
try {
|
||||
jedis.disconnect();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package org.bigbluebutton.conference.service.recorder.pubsub;
|
||||
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
|
||||
class PubsubListener extends JedisPubSub {
|
||||
|
||||
public PubsubListener() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String channel, String message) {
|
||||
|
||||
System.out.println("pubsub "+channel+":"+message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPMessage(String pattern, String channel,
|
||||
String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPSubscribe(String pattern, int subscribedChannels) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPUnsubscribe(String pattern, int subscribedChannels) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscribe(String channel, int subscribedChannels) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnsubscribe(String channel, int subscribedChannels) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
package org.bigbluebutton.conference.service.recorder.pubsub;
|
||||
|
||||
import org.bigbluebutton.conference.service.recorder.RedisServer;
|
||||
|
||||
|
||||
public class RedisListener extends RedisServer implements Runnable {
|
||||
|
||||
private PubsubListener pubsubListener;
|
||||
|
||||
public RedisListener(String server, int port) {
|
||||
super(server, port);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public void subscribe(){
|
||||
Thread t= new Thread(this);
|
||||
t.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
jedis.subscribe(pubsubListener, "bbbConferenceEvents");
|
||||
}
|
||||
|
||||
public PubsubListener getPubsubListener() {
|
||||
return pubsubListener;
|
||||
}
|
||||
public void setPubsubListener(PubsubListener pubsubListener) {
|
||||
System.out.println("setting pubsub");
|
||||
this.pubsubListener = pubsubListener;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package org.bigbluebutton.conference.service.recorder.pubsub;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
public class RedisPublisher {
|
||||
Jedis jedis;
|
||||
|
||||
public RedisPublisher(String host, int port){
|
||||
jedis= new Jedis(host,port);
|
||||
}
|
||||
|
||||
public void publish(String channel, String message){
|
||||
jedis.publish(channel, message);
|
||||
}
|
||||
|
||||
public void disconnect(){
|
||||
try {
|
||||
jedis.disconnect();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -18,15 +18,9 @@
|
||||
">
|
||||
|
||||
<bean id="roomsManager" class="org.bigbluebutton.conference.RoomsManager">
|
||||
<property name="conferenceEventListener" ref="conferenceEventListener" />
|
||||
<property name="publisher" ref="redisPublisher"></property>
|
||||
</bean>
|
||||
|
||||
<bean id="redisPublisher" class="org.bigbluebutton.conference.service.recorder.pubsub.RedisPublisher">
|
||||
<constructor-arg index="0" value="${redis.host}"/>
|
||||
<constructor-arg index="1" value="${redis.port}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="participantsHandler" class="org.bigbluebutton.conference.service.participants.ParticipantsHandler">
|
||||
<property name="participantsApplication"> <ref local="participantsApplication"/></property>
|
||||
<property name="recorderApplication"> <ref local="recorderApplication"/></property>
|
||||
@ -41,28 +35,6 @@
|
||||
<property name="participantsApplication"> <ref local="participantsApplication"/></property>
|
||||
</bean>
|
||||
|
||||
<!-- BEGIN JMS EVENTS -->
|
||||
<bean id="jmsRecorder" class="org.apache.activemq.command.ActiveMQQueue">
|
||||
<constructor-arg index="0">
|
||||
<value>RecorderEventsQueue</value>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="templateEvent" class="org.springframework.jms.core.JmsTemplate">
|
||||
<property name="connectionFactory"><ref local="connectionFactory" /></property>
|
||||
<property name="defaultDestination"><ref local="jmsRecorder" /> </property>
|
||||
</bean>
|
||||
|
||||
<bean id="recorderApplication" class="org.bigbluebutton.conference.service.recorder.RecorderApplication">
|
||||
<property name="recorder"><ref local="redisRecorder" /> </property>
|
||||
</bean>
|
||||
|
||||
<bean id="redisRecorder" class="org.bigbluebutton.conference.service.recorder.RedisDispatcher">
|
||||
<constructor-arg index="0" value="${redis.host}"/>
|
||||
<constructor-arg index="1" value="${redis.port}"/>
|
||||
</bean>
|
||||
|
||||
<!-- END JMS EVENTS -->
|
||||
<!-- BEGIN PRESENTATION -->
|
||||
<bean id="presentationRoomsManager" class="org.bigbluebutton.conference.service.presentation.PresentationRoomsManager"/>
|
||||
|
||||
@ -89,17 +61,17 @@
|
||||
<property name="presentationApplication"> <ref local="presentationApplication"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
|
||||
<!-- bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
|
||||
<property name="brokerURL">
|
||||
<value>tcp://localhost:61616</value>
|
||||
</property>
|
||||
</bean>
|
||||
</bean-->
|
||||
|
||||
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
|
||||
<!-- bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
|
||||
<constructor-arg index="0">
|
||||
<value>UpdatesQueue</value>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
</bean-->
|
||||
|
||||
<bean id="conversionUpdatesProcessor" class="org.bigbluebutton.conference.service.presentation.ConversionUpdatesProcessor">
|
||||
<property name="presentationApplication"> <ref local="presentationApplication"/></property>
|
||||
@ -109,11 +81,11 @@
|
||||
<property name="conversionUpdatesProcessor" ref="conversionUpdatesProcessor" />
|
||||
</bean>
|
||||
|
||||
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
|
||||
<!-- bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
|
||||
<property name="connectionFactory" ref="connectionFactory"/>
|
||||
<property name="destination" ref="destination"/>
|
||||
<property name="messageListener" ref="messageListener" />
|
||||
</bean>
|
||||
</bean-->
|
||||
<!-- END PRESENTATION -->
|
||||
|
||||
<!-- BEGIN CHAT -->
|
||||
@ -148,43 +120,32 @@
|
||||
<bean id="whiteboardRoomManager" class="org.bigbluebutton.conference.service.whiteboard.WhiteboardRoomManager"/>
|
||||
<!-- END WHITEBOARD -->
|
||||
|
||||
<!-- Starting the Spring Integration configuration for JMS integration -->
|
||||
|
||||
<!-- INCOMING MESSAGES -->
|
||||
<!-- endMeetingRequest -->
|
||||
<jms:inbound-channel-adapter id="jmsInEndMeetingRequest"
|
||||
destination-name="endMeetingRequestEvents"
|
||||
channel="endMeetingRequest"
|
||||
extract-payload="true">
|
||||
<integration:poller>
|
||||
<integration:interval-trigger interval="5" time-unit="SECONDS"/>
|
||||
</integration:poller>
|
||||
</jms:inbound-channel-adapter>
|
||||
<integration:channel id="endMeetingRequest"/>
|
||||
<integration:service-activator input-channel="endMeetingRequest" ref="roomsManager" method="endMeetingRequest" />
|
||||
<!-- RECORDER AND MESSAGING -->
|
||||
|
||||
<!-- OUTGOING MESSAGES -->
|
||||
<integration:gateway id="conferenceEventListener" service-interface="org.bigbluebutton.conference.IConferenceEventListener" />
|
||||
|
||||
<!-- conferenceStarted -->
|
||||
<integration:channel id="conferenceStarted" />
|
||||
<jms:outbound-channel-adapter id="conferenceStartedJmsOut" destination="conferenceStartedEvents" channel="conferenceStarted" />
|
||||
<bean id="conferenceStartedEvents" class="org.apache.activemq.command.ActiveMQQueue">
|
||||
<constructor-arg value="conferenceStartedEvents"/>
|
||||
</bean>
|
||||
|
||||
<!-- conferenceEnded -->
|
||||
<integration:channel id="conferenceEnded" />
|
||||
<jms:outbound-channel-adapter id="conferenceEndedJmsOut" destination="conferenceEndedEvents" channel="conferenceEnded" />
|
||||
<bean id="conferenceEndedEvents" class="org.apache.activemq.command.ActiveMQQueue">
|
||||
<constructor-arg value="conferenceEndedEvents"/>
|
||||
</bean>
|
||||
|
||||
<!-- participantsUpdated -->
|
||||
<integration:channel id="participantsUpdated" />
|
||||
<jms:outbound-channel-adapter id="participantsUpdatedJmsOut" destination="participantsUpdatedEvents" channel="participantsUpdated" />
|
||||
<bean id="participantsUpdatedEvents" class="org.apache.activemq.command.ActiveMQQueue">
|
||||
<constructor-arg value="participantsUpdatedEvents"/>
|
||||
<bean id="recorderApplication" class="org.bigbluebutton.conference.service.recorder.RecorderApplication">
|
||||
<property name="recorder"><ref local="redisRecorder" /> </property>
|
||||
</bean>
|
||||
|
||||
<bean id="redisRecorder" class="org.bigbluebutton.conference.service.recorder.RedisDispatcher">
|
||||
<property name="redisPool"><ref local="redisPool" /> </property>
|
||||
</bean>
|
||||
|
||||
<bean id="redisListener" class="org.bigbluebutton.conference.service.messaging.RedisListener" init-method="init">
|
||||
<property name="redisPool"><ref local="redisPool" /> </property>
|
||||
<property name="roomsManager"> <ref local="roomsManager"/></property>
|
||||
<property name="messageListener"> <ref local="messageListener"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="redisPublisher" class="org.bigbluebutton.conference.service.messaging.RedisPublisher">
|
||||
<property name="redisPool"><ref local="redisPool" /> </property>
|
||||
</bean>
|
||||
|
||||
<bean id="redisPool" class="redis.clients.jedis.JedisPool">
|
||||
<constructor-arg index="0" value="${redis.host}"/>
|
||||
<constructor-arg index="1" value="${redis.port}"/>
|
||||
</bean>
|
||||
|
||||
<!-- END RECORDER AND MESSAGING -->
|
||||
|
||||
</beans>
|
||||
|
2
bigbluebutton-web/.gitignore
vendored
2
bigbluebutton-web/.gitignore
vendored
@ -3,3 +3,5 @@
|
||||
stacktrace.log
|
||||
lib
|
||||
web-app/demo/bbb_api_conf.jsp
|
||||
target
|
||||
plugins/*
|
||||
|
@ -1,8 +1,7 @@
|
||||
#utf-8
|
||||
#Tue Apr 12 17:57:12 UTC 2011
|
||||
#Mon Jun 06 06:53:20 UTC 2011
|
||||
app.version=0.70dev
|
||||
app.servlet.version=2.4
|
||||
app.grails.version=1.1.1
|
||||
plugins.hibernate=1.1.1
|
||||
plugins.jsecurity=0.4.1
|
||||
app.name=bigbluebutton
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* BigBlueButton - http://www.bigbluebutton.org
|
||||
*
|
||||
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
|
||||
*
|
||||
* BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* $Id: $
|
||||
*/
|
@ -1,10 +1,10 @@
|
||||
#
|
||||
# These are the default properites for BigBlueButton Web application
|
||||
|
||||
dataSource.url=jdbc:mysql://localhost/bigbluebutton_dev
|
||||
dataSource.username=bbb
|
||||
dataSource.password=secret
|
||||
dataSource.driverClassName =com.mysql.jdbc.Driver
|
||||
#dataSource.url=jdbc:mysql://localhost/bigbluebutton_dev
|
||||
#dataSource.username=bbb
|
||||
#dataSource.password=secret
|
||||
#dataSource.driverClassName =com.mysql.jdbc.Driver
|
||||
|
||||
#----------------------------------------------------
|
||||
# Directory where BigBlueButton stores uploaded slides
|
||||
@ -69,7 +69,7 @@ defaultMaxUsers=20
|
||||
#----------------------------------------------------
|
||||
# This URL is where the BBB client is accessible. When a user sucessfully
|
||||
# enters a name and password, she is redirected here to load the client.
|
||||
bigbluebutton.web.serverURL=http://192.168.0.166
|
||||
bigbluebutton.web.serverURL=http://192.168.1.38
|
||||
|
||||
#----------------------------------------------------
|
||||
# Assign URL where the logged-out participant will be redirected after sign-out.
|
||||
@ -94,7 +94,7 @@ beans.presentationService.testUploadedPresentation=appkonference.txt
|
||||
# Test voiceBridge number
|
||||
beans.dynamicConferenceService.testVoiceBridge=99999
|
||||
|
||||
redisHost=192.168.0.166
|
||||
redisHost=localhost
|
||||
redisPort=6379
|
||||
|
||||
# Directory where we drop the <meeting-id-recorded>.done file
|
||||
|
@ -32,7 +32,18 @@
|
||||
<property name="dynamicConferenceService" ref="dynamicConferenceService"></property>
|
||||
</bean>
|
||||
-->
|
||||
<bean id="meetingService" class="org.bigbluebutton.api.MeetingServiceImp">
|
||||
<property name="messagingService" ref="messagingService"></property>
|
||||
</bean>
|
||||
|
||||
<bean id="messagingService" class="org.bigbluebutton.api.messaging.RedisMessagingService">
|
||||
<property name="redisPool" ref="redisPool"></property>
|
||||
</bean>
|
||||
|
||||
<bean id="redisPool" class="redis.clients.jedis.JedisPool">
|
||||
<constructor-arg index="0" value="${redisHost}"/>
|
||||
<constructor-arg index="1" value="${redisPort}"/>
|
||||
</bean>
|
||||
|
||||
<!-- Spring Integration / JMS gateways -->
|
||||
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
|
||||
@ -41,56 +52,6 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- INCOMING MESSAGES -->
|
||||
|
||||
<!-- conferenceStarted -->
|
||||
<jms:inbound-channel-adapter id="jmsInConferenceStarted"
|
||||
destination-name="conferenceStartedEvents"
|
||||
channel="conferenceStarted"
|
||||
extract-payload="true">
|
||||
<integration:poller>
|
||||
<integration:interval-trigger interval="5" time-unit="SECONDS"/>
|
||||
</integration:poller>
|
||||
</jms:inbound-channel-adapter>
|
||||
<integration:channel id="conferenceStarted"/>
|
||||
<!--integration:service-activator input-channel="conferenceStarted" ref="dynamicConferenceService" method="conferenceStarted" /-->
|
||||
|
||||
<!-- conferenceEnded -->
|
||||
<jms:inbound-channel-adapter id="jmsInConferenceEnded"
|
||||
destination-name="conferenceEndedEvents"
|
||||
channel="conferenceEnded"
|
||||
extract-payload="true">
|
||||
<integration:poller>
|
||||
<integration:interval-trigger interval="5" time-unit="SECONDS"/>
|
||||
</integration:poller>
|
||||
</jms:inbound-channel-adapter>
|
||||
<integration:channel id="conferenceEnded"/>
|
||||
<!--integration:service-activator input-channel="conferenceEnded" ref="dynamicConferenceService" method="conferenceEnded" /-->
|
||||
|
||||
<!-- participantsUpdated -->
|
||||
<jms:inbound-channel-adapter id="jmsInParticipantsUpdated"
|
||||
destination-name="participantsUpdatedEvents"
|
||||
channel="participantsUpdated"
|
||||
extract-payload="true">
|
||||
<integration:poller>
|
||||
<integration:interval-trigger interval="5" time-unit="SECONDS"/>
|
||||
</integration:poller>
|
||||
</jms:inbound-channel-adapter>
|
||||
<integration:channel id="participantsUpdated"/>
|
||||
<!--integration:service-activator input-channel="participantsUpdated" ref="dynamicConferenceService" method="participantsUpdated" /-->
|
||||
|
||||
<!-- <stream:stdout-channel-adapter id="stdout" channel="jmsinToStdoutChannel" append-newline="true"/>-->
|
||||
|
||||
<!-- OUTGOING MESSAGES -->
|
||||
<integration:gateway id="conferenceEventListener" service-interface="org.bigbluebutton.api.IApiConferenceEventListener" />
|
||||
|
||||
<!-- endMeetingRequest -->
|
||||
<integration:channel id="endMeetingRequest" />
|
||||
<jms:outbound-channel-adapter id="endMeetingRequestJmsOut" destination="endMeetingRequestEvents" channel="endMeetingRequest" />
|
||||
<bean id="endMeetingRequestEvents" class="org.apache.activemq.command.ActiveMQQueue">
|
||||
<constructor-arg value="endMeetingRequestEvents"/>
|
||||
</bean>
|
||||
|
||||
<import resource="doc-conversion.xml" />
|
||||
|
||||
</beans>
|
@ -119,14 +119,15 @@ class ApiController {
|
||||
String logoutUrl = dynamicConferenceService.processLogoutUrl(params.logoutURL);
|
||||
boolean record = dynamicConferenceService.processRecordMeeting(params.record);
|
||||
int maxUsers = dynamicConferenceService.processMaxUser(params.maxParticipants);
|
||||
String welcomeMessage = dynamicConferenceService.processWelcomeMessage(params.welcome, dialNumber, telVoice, meetingName);
|
||||
|
||||
String welcomeMessage = dynamicConferenceService.processWelcomeMessage(params.welcome == null ? "" : params.welcome, dialNumber, telVoice, meetingName);
|
||||
|
||||
// Translate the external meeting id into an internal meeting id.
|
||||
String internalMeetingId = dynamicConferenceService.getInternalMeetingId(externalMeetingId);
|
||||
Meeting existing = dynamicConferenceService.getMeeting(internalMeetingId);
|
||||
if (existing != null) {
|
||||
log.debug "Existing conference found"
|
||||
if (existing.getAttendeePassword().equals(viewerPass) && existing.getModeratorPassword().equals(modPass)) {
|
||||
if (existing.getViewerPassword().equals(viewerPass) && existing.getModeratorPassword().equals(modPass)) {
|
||||
// trying to create a conference a second time
|
||||
// return success, but give extra info
|
||||
uploadDocuments(existing);
|
||||
|
@ -59,7 +59,8 @@ public class DynamicConferenceService {
|
||||
}
|
||||
|
||||
public void createMeeting(Meeting meeting) {
|
||||
meetingService.storeMeeting(meeting)
|
||||
log.debug("Creating New Meeting...");
|
||||
meetingService.storeMeeting(meeting);
|
||||
}
|
||||
|
||||
public Meeting getMeeting(String meetingId) {
|
||||
@ -256,6 +257,7 @@ public class DynamicConferenceService {
|
||||
}
|
||||
}
|
||||
}
|
||||
return welcomeMessage;
|
||||
}
|
||||
|
||||
public void setMeetingService(MeetingService s) {
|
||||
|
0
bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy
Normal file → Executable file
0
bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy
Normal file → Executable file
316
bigbluebutton-web/pom.xml
Normal file
316
bigbluebutton-web/pom.xml
Normal file
@ -0,0 +1,316 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.bigbluebutton</groupId>
|
||||
<artifactId>bigbluebutton</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>0.70dev</version>
|
||||
|
||||
<name>A custom grails project</name>
|
||||
<description>A custom grails project</description>
|
||||
<url>http://www.myorganization.org</url>
|
||||
|
||||
<properties>
|
||||
<grails.version>1.3.7</grails.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.grails</groupId>
|
||||
<artifactId>grails-bootstrap</artifactId>
|
||||
<version>${grails.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.codehaus.gpars</groupId>
|
||||
<artifactId>gpars</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.codehaus.gant</groupId>
|
||||
<artifactId>gant_groovy1.7</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.gparallelizer</groupId>
|
||||
<artifactId>GParallelizer</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.codehaus.gant</groupId>
|
||||
<artifactId>gant_groovy1.6</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant-launcher</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ivy</groupId>
|
||||
<artifactId>ivy</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.grails</groupId>
|
||||
<artifactId>grails-crud</artifactId>
|
||||
<version>${grails.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.grails</groupId>
|
||||
<artifactId>grails-docs</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant-launcher</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>radeox</groupId>
|
||||
<artifactId>radeox</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-digester</groupId>
|
||||
<artifactId>commons-digester</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.grails</groupId>
|
||||
<artifactId>grails-gorm</artifactId>
|
||||
<version>${grails.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant-launcher</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-digester</groupId>
|
||||
<artifactId>commons-digester</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-commons-annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>antlr</groupId>
|
||||
<artifactId>antlr</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.grails</groupId>
|
||||
<artifactId>grails-test</artifactId>
|
||||
<version>${grails.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>taglibs</groupId>
|
||||
<artifactId>standard</artifactId>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Grails defaults to Ehache for the second-level Hibernate cache. -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-ehcache</artifactId>
|
||||
<version>3.3.1.GA</version>
|
||||
<exclusions>
|
||||
<!-- See http://www.slf4j.org/faq.html#IllegalAccessError -->
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
|
||||
<!-- We are pulling in ehcache-core below -->
|
||||
<exclusion>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sf.ehcache</groupId>
|
||||
<artifactId>ehcache-core</artifactId>
|
||||
<version>1.7.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- For ease of development and testing, we include the HSQLDB database. -->
|
||||
<dependency>
|
||||
<groupId>hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>1.8.0.10</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Use Log4J for logging. This artifact also pulls in the Log4J JAR. -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Needed in the case of AOP usage -->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.6.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.6.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-pool</groupId>
|
||||
<artifactId>commons-pool</artifactId>
|
||||
<version>1.5.3</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.16</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<repositories>
|
||||
<!-- Required to get hold of javassist:javassist -->
|
||||
<repository>
|
||||
<id>jboss.org</id>
|
||||
<name>jboss.org</name>
|
||||
<url>http://repository.jboss.com/maven2/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<pluginManagement />
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.grails</groupId>
|
||||
<artifactId>grails-maven-plugin</artifactId>
|
||||
<version>${grails.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>init</goal>
|
||||
<goal>maven-clean</goal>
|
||||
<goal>validate</goal>
|
||||
<goal>config-directories</goal>
|
||||
<goal>maven-compile</goal>
|
||||
<goal>maven-test</goal>
|
||||
<goal>maven-war</goal>
|
||||
<goal>maven-functional-test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>tools</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>java.vendor</name>
|
||||
<value>Sun Microsystems Inc.</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>${java.version}</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
@ -61,10 +61,12 @@ public class MeetingServiceImp implements MeetingService {
|
||||
}
|
||||
|
||||
public Collection<Meeting> getMeetings() {
|
||||
log.debug("The number of meetings are: "+meetings.size());
|
||||
return meetings.isEmpty() ? Collections.<Meeting>emptySet() : Collections.unmodifiableCollection(meetings.values());
|
||||
}
|
||||
|
||||
public void storeMeeting(Meeting m) {
|
||||
log.debug("Storing Meeting with internal id:"+m.getInternalId());
|
||||
meetings.put(m.getInternalId(), m);
|
||||
}
|
||||
|
||||
@ -102,6 +104,7 @@ public class MeetingServiceImp implements MeetingService {
|
||||
public void setMessagingService(MessagingService mess) {
|
||||
messagingService = mess;
|
||||
messagingService.addListener(new MeetingMessageListener());
|
||||
messagingService.start();
|
||||
}
|
||||
|
||||
public void setExpiredMeetingCleanupTimerTask(ExpiredMeetingCleanupTimerTask c) {
|
||||
@ -121,6 +124,7 @@ public class MeetingServiceImp implements MeetingService {
|
||||
Meeting m = getMeeting(meetingId);
|
||||
if (m != null) {
|
||||
m.setStartTime(System.currentTimeMillis());
|
||||
log.debug("Setting meeting started time...");
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,11 +133,13 @@ public class MeetingServiceImp implements MeetingService {
|
||||
Meeting m = getMeeting(meetingId);
|
||||
if (m != null) {
|
||||
m.setEndTime(System.currentTimeMillis());
|
||||
log.debug("Setting meeting end time...");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userJoined(String meetingId, String userId, String name, String role) {
|
||||
log.debug("Adding new user...");
|
||||
Meeting m = getMeeting(meetingId);
|
||||
if (m != null) {
|
||||
User user = new User(userId, name, role);
|
||||
@ -146,6 +152,7 @@ public class MeetingServiceImp implements MeetingService {
|
||||
Meeting m = getMeeting(meetingId);
|
||||
if (m != null) {
|
||||
m.userLeft(userId);
|
||||
log.debug("Removing user...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.bigbluebutton.api.messaging;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -11,22 +9,21 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisException;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
|
||||
public class RedisMessagingService implements MessagingService {
|
||||
private static Logger log = LoggerFactory.getLogger(RedisMessagingService.class);
|
||||
|
||||
private Jedis jedis;
|
||||
private final String host;
|
||||
private final int port;
|
||||
private JedisPool redisPool;
|
||||
private final Set<MessageListener> listeners = new HashSet<MessageListener>();
|
||||
|
||||
private final Executor exec = Executors.newSingleThreadExecutor();
|
||||
private Runnable pubsubListener;
|
||||
|
||||
public RedisMessagingService(String host, int port) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
public RedisMessagingService() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,12 +38,29 @@ public class RedisMessagingService implements MessagingService {
|
||||
|
||||
@Override
|
||||
public void recordMeetingInfo(String meetingId, Map<String, String> info) {
|
||||
jedis.hmset("meeting.info:" + meetingId, info);
|
||||
Jedis jedis=redisPool.getResource();
|
||||
try{
|
||||
jedis.hmset("meeting.info:" + meetingId, info);
|
||||
}catch(JedisException e){
|
||||
log.error("Cannot record the info meeting: %s",meetingId);
|
||||
}finally{
|
||||
redisPool.returnResource(jedis);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordMeetingMetadata(String meetingId, Map<String, String> metadata) {
|
||||
jedis.hmset("meeting:metadata:" + meetingId, metadata);
|
||||
Jedis jedis=redisPool.getResource();
|
||||
try{
|
||||
jedis.hmset("meeting:metadata:" + meetingId, metadata);
|
||||
}catch(JedisException e){
|
||||
log.error("Cannot record the metadata meeting: %s",meetingId);
|
||||
}finally{
|
||||
redisPool.returnResource(jedis);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -56,37 +70,48 @@ public class RedisMessagingService implements MessagingService {
|
||||
|
||||
@Override
|
||||
public void send(String channel, String message) {
|
||||
jedis.publish(channel, message);
|
||||
Jedis jedis=redisPool.getResource();
|
||||
try{
|
||||
jedis.publish(channel, message);
|
||||
}catch(JedisException e){
|
||||
log.error("Cannot publish the message %s to redis",message);
|
||||
}finally{
|
||||
redisPool.returnResource(jedis);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
jedis = new Jedis(host, port, 0);
|
||||
log.debug("Starting redis pubsub...");
|
||||
final Jedis jedis=redisPool.getResource();
|
||||
try {
|
||||
jedis.connect();
|
||||
pubsubListener = new Runnable() {
|
||||
public void run() {
|
||||
jedis.psubscribe(new PubSubListener(), "bigbluebutton:conference:*");
|
||||
jedis.psubscribe(new PubSubListener(), "bigbluebutton:meeting:*");
|
||||
}
|
||||
};
|
||||
exec.execute(pubsubListener);
|
||||
|
||||
} catch (UnknownHostException e) {
|
||||
log.error("Unknown host[" + host + "]");
|
||||
} catch (IOException e) {
|
||||
log.error("Cannot connect to [" + host + ":" + port + "]");
|
||||
} catch (JedisException e) {
|
||||
log.error("Cannot subscribe to the redis channel");
|
||||
}finally{
|
||||
redisPool.returnResource(jedis);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
try {
|
||||
jedis.disconnect();
|
||||
} catch (IOException e) {
|
||||
redisPool.destroy();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool){
|
||||
this.redisPool=redisPool;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Pubsub channels:
|
||||
@ -98,10 +123,9 @@ public class RedisMessagingService implements MessagingService {
|
||||
**/
|
||||
|
||||
private class PubSubListener extends JedisPubSub {
|
||||
private final String PATTERN_CONFERENCE="bigbluebutton:conference:*";
|
||||
private final String CHANNEL_STATUS="bigbluebutton:conference:status";
|
||||
private final String CHANNEL_JOIN="bigbluebutton:conference:join";
|
||||
private final String CHANNEL_LEAVE="bigbluebutton:conference:remove";
|
||||
private final String PATTERN_MEETING="bigbluebutton:meeting:*";
|
||||
private final String CHANNEL_STATE="bigbluebutton:meeting:state";
|
||||
private final String CHANNEL_PARTICIPANTS="bigbluebutton:meeting:participants";
|
||||
|
||||
private final String COLON=":";
|
||||
|
||||
@ -120,39 +144,51 @@ public class RedisMessagingService implements MessagingService {
|
||||
|
||||
System.out.println("redis message received. pattern:" + pattern + " channel:" + channel + " message:" + message);
|
||||
|
||||
if(pattern.equalsIgnoreCase(PATTERN_CONFERENCE)){
|
||||
String[] args = message.split(COLON);
|
||||
String[] args=message.split(COLON);
|
||||
|
||||
if(channel.equalsIgnoreCase(CHANNEL_STATUS)){
|
||||
//params extract
|
||||
String meetingId = args[0];
|
||||
String status = args[1];
|
||||
if(channel.equalsIgnoreCase(CHANNEL_STATE)){
|
||||
//params extract
|
||||
String meetingId=args[0];
|
||||
String status=args[1];
|
||||
|
||||
for (MessageListener listener : listeners) {
|
||||
if(status.equalsIgnoreCase("started")) {
|
||||
listener.meetingStarted(meetingId);
|
||||
} else if(status.equalsIgnoreCase("ended")) {
|
||||
listener.meetingStarted(meetingId);
|
||||
}
|
||||
}
|
||||
} else if(channel.equalsIgnoreCase(CHANNEL_JOIN)){
|
||||
//params extract
|
||||
String meetingId = args[0];
|
||||
String userId = args[1];
|
||||
String name = args[2];
|
||||
String role = args[3];
|
||||
|
||||
for (MessageListener listener : listeners) {
|
||||
listener.userJoined(meetingId, userId, name, role);
|
||||
}
|
||||
} else if(channel.equalsIgnoreCase(CHANNEL_LEAVE)){
|
||||
String meetingId = args[0];
|
||||
String userId = args[1];
|
||||
|
||||
for (MessageListener listener : listeners) {
|
||||
listener.userLeft(meetingId, userId);
|
||||
for (MessageListener listener : listeners) {
|
||||
if(status.equalsIgnoreCase("started")) {
|
||||
listener.meetingStarted(meetingId);
|
||||
} else if(status.equalsIgnoreCase("ended")) {
|
||||
listener.meetingStarted(meetingId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(channel.equalsIgnoreCase(CHANNEL_PARTICIPANTS)){
|
||||
//params extract
|
||||
String meetingId=args[0];
|
||||
String action=args[1];
|
||||
|
||||
if(action.equalsIgnoreCase("join")){
|
||||
String userid=args[2];
|
||||
String fullname=args[3];
|
||||
String role=args[4];
|
||||
|
||||
for (MessageListener listener : listeners) {
|
||||
listener.userJoined(meetingId, userid, fullname, role);
|
||||
}
|
||||
}
|
||||
else if(action.equalsIgnoreCase("status")){
|
||||
String userid=args[2];
|
||||
String status=args[3];
|
||||
String value=args[4];
|
||||
//missing method...
|
||||
//dynamicConferenceService.participantsUpdatedStatus(roomname, userid, status, value);
|
||||
}
|
||||
else if(action.equalsIgnoreCase("left")){
|
||||
String userid=args[2];
|
||||
|
||||
for (MessageListener listener : listeners) {
|
||||
listener.userLeft(meetingId, userid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user