diff --git a/bbb-video/.gitignore b/bbb-video/.gitignore index ba077a4031..92cadc9282 100644 --- a/bbb-video/.gitignore +++ b/bbb-video/.gitignore @@ -1 +1,4 @@ bin +build +dist +lib diff --git a/bigbluebutton-apps/build.gradle b/bigbluebutton-apps/build.gradle index f6c3b87708..2f0987971b 100755 --- a/bigbluebutton-apps/build.gradle +++ b/bigbluebutton-apps/build.gradle @@ -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' diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/IConferenceEventListener.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/IRoomListener.java similarity index 62% rename from bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/IConferenceEventListener.java rename to bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/IRoomListener.java index 0e68663cf1..ab912a62bf 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/IConferenceEventListener.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/IRoomListener.java @@ -1,38 +1,29 @@ -/** -* 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 . -* -*/ -package org.bigbluebutton.conference; - -import org.springframework.integration.annotation.Gateway; - -/* - * 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); -} +/** +* 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 . +* +*/ + +package org.bigbluebutton.conference; + +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); + + public void endAndKickAll(); +} \ No newline at end of file diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Participant.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Participant.java new file mode 100755 index 0000000000..23e8031b21 --- /dev/null +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Participant.java @@ -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 . +* +*/ +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 unmodifiableStatus; + + public Participant(Long userid, String name, String role, String externUserID, Map status) { + this.userid = userid; + this.name = name; + this.role = role; + this.externUserID = externUserID; + this.status = new ConcurrentHashMap(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; + } +} \ No newline at end of file diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/ParticipantUpdatingRoomListener.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/ParticipantUpdatingRoomListener.java index 70b2e5af0c..1d6a37a200 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/ParticipantUpdatingRoomListener.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/ParticipantUpdatingRoomListener.java @@ -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); } } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Room.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Room.java new file mode 100755 index 0000000000..8ac498796f --- /dev/null +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/Room.java @@ -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 . +* +*/ + +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 participants; + + // these should stay transient so they're not serialized in ActiveMQ messages: + //private transient Map unmodifiableMap; + private transient final Map listeners; + + public Room(String name) { + this.name = name; + participants = new ConcurrentHashMap(); + //unmodifiableMap = Collections.unmodifiableMap(participants); + listeners = new ConcurrentHashMap(); + } + + 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 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 it = participants.values().iterator(); it.hasNext(); ) { + Participant part = it.next(); + if (part.isModerator()) { + sum++; + } + } + log.debug("Returning number of moderators: " + sum); + return sum; + } + +} \ No newline at end of file diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/RoomsManager.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/RoomsManager.java index 9a52d4319f..4ecdf1462e 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/RoomsManager.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/RoomsManager.java @@ -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 rooms; - private IConferenceEventListener conferenceEventListener; - - - - /*redis pubsub*/ + //replaced with redis publisher + //private IConferenceEventListener conferenceEventListener; + 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,15 +166,12 @@ 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; } log.warn("Removing listener from a non-existing room ${roomName}"); @@ -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; diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/messaging/RedisListener.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/messaging/RedisListener.java new file mode 100755 index 0000000000..451150b3c5 --- /dev/null +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/messaging/RedisListener.java @@ -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 map=new HashMap(); + 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; + } + + +} diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/messaging/RedisPublisher.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/messaging/RedisPublisher.java new file mode 100755 index 0000000000..f0cb88f343 --- /dev/null +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/messaging/RedisPublisher.java @@ -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; + } + +} diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsApplication.java index b6c286d82f..0b2ae654fa 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsApplication.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsApplication.java @@ -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; } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsService.java index 2392660607..0f008533d8 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsService.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/participants/ParticipantsService.java @@ -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 diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java index bf11a05eb1..35353d3959 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/presentation/ConversionUpdatesMessageListener.java @@ -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()); } } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/Recorder.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/Recorder.java index 7830baf3f0..e7a2f38e79 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/Recorder.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/Recorder.java @@ -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); diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RecorderEventDispatcher.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RecorderEventDispatcher.java deleted file mode 100755 index 45fd5c86fa..0000000000 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RecorderEventDispatcher.java +++ /dev/null @@ -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 . -* -* ===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"); - } -} diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RedisDispatcher.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RedisDispatcher.java index 0e01a84672..b1365f3742 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RedisDispatcher.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RedisDispatcher.java @@ -7,30 +7,26 @@ import redis.clients.jedis.JedisException; import redis.clients.jedis.JedisPool; public class RedisDispatcher implements Recorder { - private static final String COLON=":"; - private String host; - private int port; - - private Jedis jedis; - + private static final String COLON=":"; + JedisPool redisPool; -// 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; + } + } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RedisServer.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RedisServer.java deleted file mode 100755 index 8a7340f0dc..0000000000 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/RedisServer.java +++ /dev/null @@ -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(); - } - } -} diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/PubsubListener.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/PubsubListener.java deleted file mode 100755 index 40f3867e7f..0000000000 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/PubsubListener.java +++ /dev/null @@ -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 - - } - -} - diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/RedisListener.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/RedisListener.java deleted file mode 100755 index a5bb8d9868..0000000000 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/RedisListener.java +++ /dev/null @@ -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; - - } - -} diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/RedisPublisher.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/RedisPublisher.java deleted file mode 100755 index 8b01fc795f..0000000000 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/recorder/pubsub/RedisPublisher.java +++ /dev/null @@ -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(); - } - } -} diff --git a/bigbluebutton-apps/src/main/webapp/WEB-INF/bbb-apps.xml b/bigbluebutton-apps/src/main/webapp/WEB-INF/bbb-apps.xml index 57d7a46b2f..5eb3e7da64 100755 --- a/bigbluebutton-apps/src/main/webapp/WEB-INF/bbb-apps.xml +++ b/bigbluebutton-apps/src/main/webapp/WEB-INF/bbb-apps.xml @@ -18,14 +18,8 @@ "> - - - - - - @@ -41,28 +35,6 @@ - - - - RecorderEventsQueue - - - - - - - - - - - - - - - - - - @@ -89,17 +61,17 @@ - + - + @@ -109,11 +81,11 @@ - + @@ -148,43 +120,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bigbluebutton-web/.gitignore b/bigbluebutton-web/.gitignore index 50a0af9961..859e010422 100644 --- a/bigbluebutton-web/.gitignore +++ b/bigbluebutton-web/.gitignore @@ -3,3 +3,5 @@ stacktrace.log lib web-app/demo/bbb_api_conf.jsp +target +plugins/* diff --git a/bigbluebutton-web/application.properties b/bigbluebutton-web/application.properties index 27f82d14d4..3054bfa6fb 100755 --- a/bigbluebutton-web/application.properties +++ b/bigbluebutton-web/application.properties @@ -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 diff --git a/bigbluebutton-web/grails-app/conf/DataSource.groovy b/bigbluebutton-web/grails-app/conf/DataSource.groovy deleted file mode 100755 index a97dcfee3c..0000000000 --- a/bigbluebutton-web/grails-app/conf/DataSource.groovy +++ /dev/null @@ -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 . - * - * $Id: $ - */ diff --git a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties index c8a0c39f58..ac053df2d2 100755 --- a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties +++ b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties @@ -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 .done file diff --git a/bigbluebutton-web/grails-app/conf/spring/resources.xml b/bigbluebutton-web/grails-app/conf/spring/resources.xml index 140eb6974a..2393f099dc 100755 --- a/bigbluebutton-web/grails-app/conf/spring/resources.xml +++ b/bigbluebutton-web/grails-app/conf/spring/resources.xml @@ -32,65 +32,26 @@ --> + + + + + + + + + + + + - tcp://localhost:61616 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index 8034a50c70..92a33da546 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -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); diff --git a/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/DynamicConferenceService.groovy b/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/DynamicConferenceService.groovy index c23e359266..536185c62e 100755 --- a/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/DynamicConferenceService.groovy +++ b/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/DynamicConferenceService.groovy @@ -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) { @@ -255,7 +256,8 @@ public class DynamicConferenceService { break } } - } + } + return welcomeMessage; } public void setMeetingService(MeetingService s) { diff --git a/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy b/bigbluebutton-web/grails-app/services/org/bigbluebutton/web/services/PresentationService.groovy old mode 100644 new mode 100755 diff --git a/bigbluebutton-web/pom.xml b/bigbluebutton-web/pom.xml new file mode 100644 index 0000000000..1b79537576 --- /dev/null +++ b/bigbluebutton-web/pom.xml @@ -0,0 +1,316 @@ + + + 4.0.0 + org.bigbluebutton + bigbluebutton + war + 0.70dev + + A custom grails project + A custom grails project + http://www.myorganization.org + + + 1.3.7 + + + + + org.grails + grails-bootstrap + ${grails.version} + + + org.codehaus.gpars + gpars + + + org.codehaus.gant + gant_groovy1.7 + + + org.gparallelizer + GParallelizer + + + org.codehaus.gant + gant_groovy1.6 + + + org.apache.ant + ant + + + org.apache.ant + ant-launcher + + + org.apache.ivy + ivy + + + + + + org.grails + grails-crud + ${grails.version} + + + org.grails + grails-docs + + + org.apache.ant + ant + + + org.apache.ant + ant-launcher + + + org.springframework + spring-test + + + radeox + radeox + + + commons-digester + commons-digester + + + javax.persistence + persistence-api + + + junit + junit + + + + + + org.grails + grails-gorm + ${grails.version} + + + org.apache.ant + ant + + + org.apache.ant + ant-launcher + + + commons-digester + commons-digester + + + junit + junit + + + org.hibernate + hibernate + + + org.hibernate + hibernate-annotations + + + org.hibernate + hibernate-commons-annotations + + + antlr + antlr + + + + + + org.grails + grails-test + ${grails.version} + test + + + + javax.servlet + jstl + 1.1.2 + + + + taglibs + standard + 1.1.2 + + + + + org.hibernate + hibernate-ehcache + 3.3.1.GA + + + + org.slf4j + slf4j-api + + + + + net.sf.ehcache + ehcache + + + + + + net.sf.ehcache + ehcache-core + 1.7.1 + + + org.slf4j + slf4j-api + + + + + + + hsqldb + hsqldb + 1.8.0.10 + + + + + org.slf4j + slf4j-api + 1.5.8 + runtime + + + org.slf4j + slf4j-log4j12 + 1.5.8 + runtime + + + + + org.aspectj + aspectjweaver + 1.6.8 + + + + org.aspectj + aspectjrt + 1.6.8 + + + + commons-codec + commons-codec + 1.3 + + + + commons-collections + commons-collections + 3.2.1 + + + + commons-pool + commons-pool + 1.5.3 + + + + + + + + log4j + log4j + 1.2.16 + runtime + + + + + + + + jboss.org + jboss.org + http://repository.jboss.com/maven2/ + + + + + + + + + org.grails + grails-maven-plugin + ${grails.version} + true + + + + init + maven-clean + validate + config-directories + maven-compile + maven-test + maven-war + maven-functional-test + + + + + + + maven-compiler-plugin + + 1.5 + 1.5 + + + + + + + + tools + + + java.vendor + Sun Microsystems Inc. + + + + + com.sun + tools + ${java.version} + system + ${java.home}/../lib/tools.jar + + + + + diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingServiceImp.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingServiceImp.java index 142d949ab3..ca3f25a95a 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingServiceImp.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/MeetingServiceImp.java @@ -61,10 +61,12 @@ public class MeetingServiceImp implements MeetingService { } public Collection getMeetings() { + log.debug("The number of meetings are: "+meetings.size()); return meetings.isEmpty() ? Collections.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..."); } } } diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java index 1a28b16bf2..8586e0818e 100755 --- a/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java +++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java @@ -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 listeners = new HashSet(); 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 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 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,36 +70,47 @@ 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; + } /* @@ -98,13 +123,12 @@ 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 COLON=":"; + 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=":"; + public PubSubListener() { super(); } @@ -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); - - if(channel.equalsIgnoreCase(CHANNEL_STATUS)){ - //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); + String[] args=message.split(COLON); + + 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_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); + } + } + } }