Merge remote-tracking branch 'upstream/master' into v1.1.0-rap-on-resque

This commit is contained in:
Leonardo Crauss Daronco 2017-10-09 16:37:28 -03:00
commit af87bc2d3f
2887 changed files with 153865 additions and 70003 deletions

625
DEVELOPMENT.md Normal file → Executable file
View File

@ -1,371 +1,27 @@
This document provides instructions for developers to setup their
environment and work on the upcoming BBB 1.1 (tentative release version).
environment and work on the upcoming BBB 2.0 (tentative release version).
## Install BBB 1.0
## Install BBB 1.1
Make sure you have a working BBB 1.0 before you proceed with the instructions below.
Follow the (install instructions)[http://docs.bigbluebutton.org/install/install.html] for 1.1.
## Install OpenJDK 8
Make sure you have a working BBB 1.1 before you proceed with the instructions below.
```
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk
```
## Setup development environment
Change the default jre. Choose Java 8.
Setup your development environment following these (instructions)[http://docs.bigbluebutton.org/dev/setup.html]
```
sudo update-alternatives --config java
```
## Checkout development branch
Change the default jdk. Choose Jdk8
Checkout the development branch `move-java-classes-from-bbb-web-to-bbb-common-web` from this (repository)[https://github.com/ritzalam/bigbluebutton]
```
sudo update-alternatives --config javac
```
Open nine (9) terminal windows so you will dedicate one window for each bbb-component.
You can name them client, bbb-apps, apps-common, red5, akka-apps, akka-fsesl, bbb-web, common-web, and messages.
## Environment Variables
Edit `~/.profile` and change `JAVA_HOME`
```
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
```
Save the file and refresh environment vars.
```
source ~/.profile
```
## Update Development Tools
### Install The Core Development Tools
```
sudo apt-get install git-core ant
```
### Install Gradle
```
cd ~/dev/tools
wget http://services.gradle.org/distributions/gradle-2.12-bin.zip
unzip gradle-2.12-bin.zip
ln -s gradle-2.12 gradle
```
### Install Grails
```
cd ~/dev/tools
wget https://github.com/grails/grails-core/releases/download/v2.5.2/grails-2.5.2.zip
unzip grails-2.5.2.zip
ln -s grails-2.5.2 grails
```
### Install Maven
```
cd ~/dev/tools
wget apache.parentingamerica.com//maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.zip
unzip apache-maven-3.3.3-bin.zip
ln -s apache-maven-3.3.3 maven
```
### Install sbt
```
cd ~/dev/tools
wget https://dl.bintray.com/sbt/native-packages/sbt/0.13.9/sbt-0.13.9.tgz
tar zxvf sbt-0.13.9.tgz
```
In the next step, you need to get the Apache Flex 4.13.0 SDK package.
**Note:** Even though we're downloading the Apache Flex 4.13.0 SDK, BigBlueButton is developed and built with Flex 3 compatibility mode enabled.
First, you need to download the SDK tarball from an Apache mirror site and then unpack it.
```
wget https://archive.apache.org/dist/flex/4.13.0/binaries/apache-flex-sdk-4.13.0-bin.tar.gz
tar xvfz apache-flex-sdk-4.13.0-bin.tar.gz
```
Once Flex SDK is unpacked, you need to download the Adobe Flex SDK. We'll do this step manually in case the download fails (if it does, remove the incomplete file and issue the `wget` command again).
```
cd apache-flex-sdk-4.13.0-bin/
mkdir -p in/
wget http://download.macromedia.com/pub/flex/sdk/builds/flex4.6/flex_sdk_4.6.0.23201B.zip -P in/
```
Once the SDK has downloaded, we can use its `build.xml` script to automatically download the remaining third-party tools.
```
ant -f frameworks/build.xml thirdparty-downloads
```
After Flex downloads the remaining third-party tools, you need to modify their permissions.
```
sudo find ~/dev/tools/apache-flex-sdk-4.13.0-bin -type d -exec chmod o+rx '{}' \;
chmod 755 ~/dev/tools/apache-flex-sdk-4.13.0-bin/bin/*
sudo chmod -R +r ~/dev/tools/apache-flex-sdk-4.13.0-bin
```
Next, create a linked directory with a shortened name for easier referencing.
```
ln -s ~/dev/tools/apache-flex-sdk-4.13.0-bin ~/dev/tools/flex
```
The next step in setting up the Flex SDK environment is to download a Flex library for video.
```
cd ~/dev/tools/
mkdir -p apache-flex-sdk-4.13.0-bin/frameworks/libs/player/11.2
cd apache-flex-sdk-4.13.0-bin/frameworks/libs/player/11.2
wget http://fpdownload.macromedia.com/get/flashplayer/installers/archive/playerglobal/playerglobal11_2.swc
mv -f playerglobal11_2.swc playerglobal.swc
```
The last step to have a working Flex SDK is to configure it to work with playerglobal 11.2
```
cd ~/dev/tools/apache-flex-sdk-4.13.0-bin
sudo sed -i "s/11.1/11.2/g" frameworks/flex-config.xml
sudo sed -i "s/<swf-version>14<\/swf-version>/<swf-version>15<\/swf-version>/g" frameworks/flex-config.xml
sudo sed -i "s/{playerglobalHome}\/{targetPlayerMajorVersion}.{targetPlayerMinorVersion}/libs\/player\/11.2/g" frameworks/flex-config.xml
```
With the tools installed, you need to add a set of environment variables to your `.profile` to access these tools.
```
vi ~/.profile
```
Copy-and-paste the following text at bottom of `.profile`.
```
export GRAILS_HOME=$HOME/dev/tools/grails
export PATH=$PATH:$GRAILS_HOME/bin
export FLEX_HOME=$HOME/dev/tools/flex
export PATH=$PATH:$FLEX_HOME/bin
export GRADLE_HOME=$HOME/dev/tools/gradle
export PATH=$PATH:$GRADLE_HOME/bin
export SBT_HOME=$HOME/dev/tools/sbt
export PATH=$PATH:$SBT_HOME/bin
export MAVEN_HOME=$HOME/dev/tools/maven
export PATH=$PATH:$MAVEN_HOME/bin
```
Reload your profile to use these tools (this will happen automatically when you next login).
```
source ~/.profile
```
Check that the tools are now in your path by running the following command.
```
$ mxmlc -version
Version 4.13.0 build 20140701
```
## Setup Red5
```
cd /usr/share
# Make a backup of the deployed red5
sudo mv red5 red5-orig
# Symlink red5 to old red5
sudo ln -s red5-orig red5
```
## Build Red5
Build red5-parent
```
cd ~/dev
git clone https://github.com/bigbluebutton/red5-parent.git
cd red5-parent/
git checkout snapshot-mar-30-2016
mvn install
```
Build red5-io
```
cd ~/dev
git clone https://github.com/bigbluebutton/red5-io.git
cd red5-io
git checkout snapshot-mar-30-2016
./bbb-build.sh
```
Build red5-server-common
```
cd ~/dev
git clone https://github.com/bigbluebutton/red5-server-common.git
cd red5-server-common
git checkout snapshot-mar-30-2016
./bbb-build.sh
```
Build red5-server
```
cd ~/dev
git clone https://github.com/bigbluebutton/red5-server.git
cd red5-server
git checkout snapshot-mar-30-2016
./build-red5.sh
# Deploy red5, this will copy the new red5 to /usr/share
# and modify the symlink you created above.
./deploy-red5.sh
```
# Developing the client
# Client Development
With the development environment checked out and the code cloned, we are ready to start developing!
This section will walk you through making a simple change to the BigBlueButton client.
## Setting up the environment
The first thing you need to do is to copy the template `config.xml` file to the build directory for the client.
```
cd ~/dev/bigbluebutton/
cp bigbluebutton-client/resources/config.xml.template bigbluebutton-client/src/conf/config.xml
```
The `config.xml` file is one of the first files loaded by the BigBlueButton client when it connects to the server. The `config.xml` file tells BigBlueButton client how to load the remaining components (such as chat module, deskshare module, video conf module, etc.) and sets a number of configuration parameters for each component. The `config.xml` specifies the hostname (or IP address) for loading each component.
Let's look at the first ten lines of the `config.xml` file you just copied.
```
$ head -n 10 bigbluebutton-client/src/conf/config.xml
<?xml version="1.0" ?>
<config>
<localeversion suppressWarning="false">0.9.0</localeversion>
<version>VERSION</version>
<help url="http://HOST/help.html"/>
<javaTest url="http://HOST/testjava.html"/>
<porttest host="HOST" application="video/portTest" timeout="10000"/>
<bwMon server="HOST" application="video/bwTest"/>
<application uri="rtmp://HOST/bigbluebutton" host="http://HOST/bigbluebutton/api/enter"/>
<language userSelectionEnabled="true" />
```
You will see the word `HOST` where there would be configured hostname/IP address. You need to change the text `HOST` to the IP address (or hostname) of your BigBlueButton server. For example, if the IP address of your BigBlueButton server is `192.168.1.145`, then using the following command you can easily substitute all occurrences of `HOST` with `192.168.1.145`.
Note: Don't copy-and-paste the following command as-is: the address `192.168.1.145` is likely not the correct IP address (or hostname) for your BigBlueButton server. Substitute the IP address (or hostname) for your BigBlueButton server.
```
sed -i s/HOST/192.168.1.145/g bigbluebutton-client/src/conf/config.xml
```
After you've done the above command, take a quick look at the file and ensure all instances of `HOST` are properly replaced with the IP address (or hostname) of your BigBlueButton server.
The `config.xml` is ultimately loaded by the BigBlueButton client when a user joins a session on the server.
Later on, when you deploy your modified client to the BigBlueButton server, there will be two BigBlueButton clients on your server: your modified BigBlueButton client and the default BigBlueButton packaged client (again, this is good as you can switch back and forth). However, the BigBlueButton configuration command `sudo bbb-conf ` only modifies the packaged BigBlueButton client and you will need to mirror any changes to the packaged config.xml to the secondary client's config.xml.
Next, you need to setup nginx to redirect calls to the client towards your development version. If you don't already have nginx client development file at `/etc/bigbluebutton/nginx/client_dev`, create one with the following command.
**NOTE:** Make sure to replace "firstuser" with your own username if it's different.
```
echo "
location /client/BigBlueButton.html {
root /home/firstuser/dev/bigbluebutton/bigbluebutton-client;
index index.html index.htm;
expires 1m;
}
# BigBlueButton Flash client.
location /client {
root /home/firstuser/dev/bigbluebutton/bigbluebutton-client;
index index.html index.htm;
}
" | sudo tee /etc/bigbluebutton/nginx/client_dev
```
Check the contents to ensure it matches below.
Again, make sure you change `/home/firstuser` to match your home directory.
```
$ cat /etc/bigbluebutton/nginx/client_dev
location /client/BigBlueButton.html {
root /home/firstuser/dev/bigbluebutton/bigbluebutton-client;
index index.html index.htm;
expires 1m;
}
# BigBlueButton Flash client.
location /client {
root /home/firstuser/dev/bigbluebutton/bigbluebutton-client;
index index.html index.htm;
}
```
These rules tell nginx where to find the BigBlueButton client. Currently, nginx is using the rules with the default BigBlueButton client through a symbolic link.
```
$ ls -al /etc/bigbluebutton/nginx/client.nginx
lrwxrwxrwx 1 root root 31 2013-05-05 15:44 /etc/bigbluebutton/nginx/client.nginx -> /etc/bigbluebutton/nginx/client
```
Modify this symbolic link so it points to the development directory for your BigBlueButton client.
```
sudo ln -f -s /etc/bigbluebutton/nginx/client_dev /etc/bigbluebutton/nginx/client.nginx
```
Check that the modifications are in place.
```
$ ls -al /etc/bigbluebutton/nginx/client.nginx
lrwxrwxrwx 1 root root 35 2013-05-05 21:07 /etc/bigbluebutton/nginx/client.nginx -> /etc/bigbluebutton/nginx/client_dev
```
Now we need to restart nginx so our changes take effect.
```
$ sudo service nginx restart
Restarting nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
configuration file /etc/nginx/nginx.conf test is successful nginx.
```
Now, when you launch the BigBlueButton client, nginx will serve the client from your development directory. Next, we need to rebuild the client.
## Building the client
Let's now build the client. Note we're going to build and run the client to make sure it works before making any changes to the source.
First, we'll build the locales (language translation files). If you are not modifying the locales, you only need to do this once.
On you bbb-client terminal, run the following commands.
```
cd ~/dev/bigbluebutton/bigbluebutton-client
@ -392,42 +48,12 @@ ant
This will create a build of the BigBlueButton client in the `/home/firstuser/dev/bigbluebutton/bigbluebutton-client/client` directory.
## Setup nginx
Create file `/etc/bigbluebutton/nginx/screenshare.nginx` and add the following:
```
# Handle desktop sharing. Forwards
# requests to Red5 on port 5080.
location /screenshare {
proxy_pass http://127.0.0.1:5080;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
include fastcgi_params;
}
```
Restart nginx
```
sudo service nginx restart
```
## Build BBB Red5 Applications
Turn off red5 service
On your red5 terminal, turn off red5 service
```
sudo service bbb-red5 stop
sudo systemctl stop red5
```
You need to make `red5/webapps` writeable. Otherwise, you will get a permission error when you try to deploy into Red5.
@ -438,90 +64,55 @@ sudo chmod -R 777 /usr/share/red5/webapps
### Build common-message
On your message terminal, run the following commands. Other components depends on this, so build this first.
```
cd ~/dev/bigbluebutton/bbb-common-message/
sbt clean
sbt publish
sbt publishLocal
```
### Build bbb-apps
We've split bbb-apps into bbb-apps-common and bigbluebutton-apps. We need to build bbb-apps-common first.
On your apps-common terminal, build the bbb-apps-common component.
```
cd ~/dev/bigbluebutton/bbb-apps-common/
# Force updating of bbb-commons-message
sbt clean
# Build and share library
sbt publish publishLocal
```
On your bbb-apps terminal, run the following commands.
```
cd ~/dev/bigbluebutton/bigbluebutton-apps/
# To make sure the lib folder is clean of old dependencies especially if you've used this
# dev environment for BBB 1.1, delete the contents of the lib directory. You can only to
# do once.
rm lib/*
# Force updating dependencies (bbb-apps-common)
gradle clean
gradle resolveDeps
gradle clean war deploy
```
### Build bbb-voice
```
cd ~/dev/bigbluebutton/bbb-voice
```
Edit `src/main/webapp/WEB-INF/bigbluebutton-sip.properties`
Make sure the IP addresses point to yout BBB server.
```
bbb.sip.app.ip=192.168.74.128
# The ip and port of the FreeSWITCH server
freeswitch.ip=192.168.74.128
```
```
gradle resolveDeps
gradle clean war deploy
```
### Build bbb-video
```
cd ~/dev/bigbluebutton/bbb-video/
gradle resolveDeps
gradle clean war deploy
```
### Build bbb-screenshare
```
cd ~/dev/bigbluebutton/bbb-screenshare/app
```
Edit `src/main/webapp/WEB-INF/screenshare.properties`
Make sure the following points to your BBB server.
```
streamBaseUrl=rtmp://192.168.74.128/screenshare
jnlpUrl=http://192.168.74.128/screenshare
jnlpFile=http://192.168.74.128/screenshare/screenshare.jnlp
```
Build and deploy
```
./deploy.sh
```
## Stop services
```
sudo /etc/init.d/bbb-red5 stop
sudo service bbb-apps-akka stop
sudo service bbb-fsesl-akka stop
```
Remove old `bbb-web` app from tomcat
```
sudo rm /var/lib/tomcat7/webapps/bigbluebutton.war
gradle war deploy
```
## Manually start services
### Run Red5
Open up a terminal.
On your red5 terminal, start red5.
```
cd /usr/share/red5
@ -530,24 +121,78 @@ sudo -u red5 ./red5.sh
### Run Akka Apps
Open up another terminal.
On your akka-apps terminal, start akka-apps
```
cd ~/dev/bigbluebutton/akka-bbb-apps
# To make sure the lib folder is clean of old dependencies especially if you've used this
# dev environment for BBB 1.1, delete the contents of the lib directory. You can only to
# do once.
rm lib_managed/*
# We need to stop the existing packaged akka-apps
sudo systemctl stop bbb-apps-akka
# Now we can run our own
sbt clean
sbt run
```
### Run Akka FSESL App
Open another terminal
On your akka-fsesl terminal, start akka-fsesl
```
cd ~/dev/bigbluebutton/akka-bbb-fsesl
# To make sure the lib folder is clean of old dependencies especially if you've used this
# dev environment for BBB 1.1, delete the contents of the lib directory. You can only to
# do once.
rm lib_managed/*
# We need to stop the existing packaged akka-fsesl
sudo systemctl stop bbb-fsesl-akka
# Now we can run our own
sbt clean
sbt run
```
### Build bbb-web
We've split up bbb-web into bbb-common-web and bigbluebutton-web. We need to build
bbb-common-web first.
On your common-web terminal, run these commands
```
cd ~/dev/bigbluebutton/bbb-common-web/
# To make sure the lib folder is clean of old dependencies especially if you've used this
# dev environment for BBB 1.1, delete the contents of the lib directory. You can only to
# do once.
rm lib_managed/*
# Force updating of dependencies especially bbb-commons-message
sbt clean
sbt publish publishLocal
```
### Run bbb-web
First we need to remove the old `bbb-web` app from tomcat to avoid duplicate messages
```
sudo cp /var/lib/tomcat7/webapps/bigbluebutton.war /var/lib/tomcat7/webapps/bigbluebutton.war-packaged
sudo rm -r /var/lib/tomcat7/webapps/bigbluebutton
```
On your bbb-web terminal, start bbb-web
```
cd ~/dev/bigbluebutton/bigbluebutton-web
```
@ -565,15 +210,83 @@ securitySalt=856d5e0197b1aa0cf79897841142a5f6
Start bbb-web
```
# To make sure the lib folder is clean of old dependencies especially if you've used this
# dev environment for BBB 1.1, delete the contents of the lib directory. You can only to
# do once.
rm lib/*
gradle clean
gradle resolveDeps
grails clean
sudo chmod -R ugo+rwx /var/log/bigbluebutton
grails -Dserver.port=8888 run-war
```
If things started without errors, congrats!
## Converting and Adding new messages
In bigbluebutton-apps, from [InMessages.scala](https://github.com/bigbluebutton/bigbluebutton/blob/bbb-2x-mconf/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala) choose the message to convert.
```
case class UserShareWebcam(meetingID: String, userId: String, stream: String) extends InMessage
```
In bbb-apps-common, add new message in [BbbCoreEnvelope.scala](https://github.com/bigbluebutton/bigbluebutton/blob/bbb-2x-mconf/bbb-common-message/src/main/scala/org/bigbluebutton/common2/messages/BbbCoreEnvelope.scala)
```
object UserShareWebcamMsg { val NAME = "UserShareWebcamMsg" }
case class UserShareWebcamMsg(header: BbbClientMsgHeader, body: UserShareWebcamMsgBody)
```
Define `UserShareWebcamMsgBody` in `MessageBody.scala`
```
case class UserShareWebcamMsgBody(userId: String, stream: String)
```
From the client, send message as
```
{
"header": {
"name": "UserShareWebcamMsg",
"meetingId": "foo-meetingId",
"userId": "bar-userId"
},
"body": {
"streamId": "my-webcam-stream"
}
}
```
In [ReceivedJsonMsgHandlerActor](https://github.com/bigbluebutton/bigbluebutton/blob/bbb-2x-mconf/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala), deserialize the message with implementation in [ReceivedJsonMsgDeserializer](https://github.com/bigbluebutton/bigbluebutton/blob/bbb-2x-mconf/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgDeserializer.scala).
```
case UserShareWebcamMsg.NAME =>
for {
m <- routeUserShareWebcamMsg(jsonNode)
} yield {
send(envelope, m)
}
```
Route the message in [ReceivedMessageRouter](https://github.com/bigbluebutton/bigbluebutton/blob/bbb-2x-mconf/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/ReceivedMessageRouter.scala).
```
def send(envelope: BbbCoreEnvelope, msg: UserShareWebcamMsg): Unit = {
val event = BbbMsgEvent(msg.header.meetingId, BbbCommonEnvCoreMsg(envelope, msg))
publish(event)
}
```
Handle the message in [MeestingActor](https://github.com/bigbluebutton/bigbluebutton/blob/bbb-2x-mconf/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala) replacing the old implementation.
A complete example would be the `ValidateAuthTokenReqMsg`.

View File

@ -1,15 +1,17 @@
BigBlueButton
=============
BigBlueButton is an open source web conferencing system for on-line learning.
BigBlueButton is an open source web conferencing system.
We believe that every student with a web browser should have access to a high-quality on-line learning experience. We intend to make that possible with BigBlueButton.
BigBlueButton supports real-time sharing of audio, video, slides (with whiteboard controls), chat, and the screen. Instructors can engage remote students with polling, emojis, and breakout rooms. BigBlueButton can record and playback all content shared in a session.
BigBlueButton supports real-time sharing of slides (PDF and any document readable by LibreOffice), webcams, whiteboard, chat, voice over IP (using FreeSWITCH), and desktop. It can record and playback all content shared in a session. The use cases for BigBlueButton are
We designed BigBlueButton for online learning (though it can be used for many [other applications](http://www.c4isrnet.com/story/military-tech/disa/2015/02/11/disa-to-save-12m-defense-collaboration-services/23238997/)). The educational use cases for BigBlueButton are
* One-to-one on-line tutoring
* Small group collaboration
* On-line classes (50 or less)
* On-line classes
For more information on the latest release -- including installation instructions, demo server, API, and overview of architecture -- see [http://docs.bigbluebutton.org/](http://docs.bigbluebutton.org/).
BigBlueButton runs on a Ubuntu 16.04 64-bit server. If you follow the [installation instructions](http://docs.bigbluebutton.org/install/install.html), we guarantee you will have BigBlueButton installed and running within 30 minutes (or your money back :-).
BigBlueButton and the BigBlueButton Logo are trademarks of [BigBlueButton Inc] (http://bigbluebutton.org) .
For full technical documentation BigBlueButton -- including architecture, features, API, and GreenLight (the default front-end) -- see [http://docs.bigbluebutton.org/](http://docs.bigbluebutton.org/).
BigBlueButton and the BigBlueButton Logo are trademarks of [BigBlueButton Inc](http://bigbluebutton.org) .

View File

@ -6,7 +6,7 @@ organization := "org.bigbluebutton"
version := "0.0.2"
scalaVersion := "2.11.7"
scalaVersion := "2.12.2"
scalacOptions ++= Seq(
"-unchecked",
@ -14,7 +14,7 @@ scalacOptions ++= Seq(
"-Xlint",
"-Ywarn-dead-code",
"-language:_",
"-target:jvm-1.7",
"-target:jvm-1.8",
"-encoding", "UTF-8"
)
@ -25,6 +25,7 @@ resolvers ++= Seq(
)
resolvers += Resolver.sonatypeRepo("releases")
resolvers += Resolver.typesafeRepo("releases")
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) )
@ -37,37 +38,73 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console",
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports")
val akkaVersion = "2.5.1"
val scalaTestVersion = "3.0.1"
libraryDependencies ++= {
val akkaVersion = "2.3.14"
val akkaStreamV = "1.0"
val scalaTestV = "2.2.4"
Seq(
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion % "test",
"com.typesafe.akka" %% "akka-slf4j" % akkaVersion,
"com.typesafe.akka" %% "akka-stream-experimental" % akkaStreamV,
"com.typesafe.akka" %% "akka-http-core-experimental" % akkaStreamV,
"com.typesafe.akka" %% "akka-http-experimental" % akkaStreamV,
"com.typesafe.akka" %% "akka-http-spray-json-experimental" % akkaStreamV,
"com.typesafe.akka" %% "akka-http-testkit-experimental" % akkaStreamV,
"org.scalatest" % "scalatest_2.11" % scalaTestV % "test",
"ch.qos.logback" % "logback-classic" % "1.0.13" % "runtime",
"org.pegdown" % "pegdown" % "1.4.0",
"junit" % "junit" % "4.11",
"com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.10",
"joda-time" % "joda-time" % "2.3",
"com.google.code.gson" % "gson" % "2.5",
"redis.clients" % "jedis" % "2.7.2",
"org.apache.commons" % "commons-lang3" % "3.2",
"org.bigbluebutton" % "bbb-common-message" % "0.0.18-SNAPSHOT",
"io.spray" %% "spray-json" % "1.3.2"
"org.apache.commons" % "commons-lang3" % "3.2"
)
}
seq(Revolver.settings: _*)
libraryDependencies += "org.bigbluebutton" % "bbb-common-message_2.12" % "0.0.19-SNAPSHOT"
// https://mvnrepository.com/artifact/org.scala-lang/scala-library
libraryDependencies += "org.scala-lang" % "scala-library" % scalaVersion.value
// https://mvnrepository.com/artifact/org.scala-lang/scala-compiler
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
// https://mvnrepository.com/artifact/com.typesafe.akka/akka-actor_2.12
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.12" % akkaVersion
// https://mvnrepository.com/artifact/com.typesafe.akka/akka-slf4j_2.12
libraryDependencies += "com.typesafe.akka" % "akka-slf4j_2.12" % akkaVersion
// https://mvnrepository.com/artifact/com.github.etaty/rediscala_2.12
libraryDependencies += "com.github.etaty" % "rediscala_2.12" % "1.8.0"
libraryDependencies += "com.softwaremill.quicklens" %% "quicklens" % "1.4.8"
libraryDependencies += "com.google.code.gson" % "gson" % "2.8.0"
libraryDependencies += "joda-time" % "joda-time" % "2.9.9"
libraryDependencies += "io.spray" % "spray-json_2.12" % "1.3.3"
libraryDependencies += "org.parboiled" % "parboiled-scala_2.12" % "1.1.8"
// https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-scala_2.12
libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.12" % "2.8.8"
// For generating test reports
libraryDependencies += "org.pegdown" % "pegdown" % "1.6.0" % "test"
// https://mvnrepository.com/artifact/com.typesafe.akka/akka-testkit_2.12
libraryDependencies += "com.typesafe.akka" % "akka-testkit_2.12" % akkaVersion % "test"
// https://mvnrepository.com/artifact/org.scalactic/scalactic_2.12
libraryDependencies += "org.scalactic" % "scalactic_2.12" % "3.0.3" % "test"
// https://mvnrepository.com/artifact/org.scalatest/scalatest_2.12
libraryDependencies += "org.scalatest" % "scalatest_2.12" % scalaTestVersion % "test"
libraryDependencies += "org.mockito" % "mockito-core" % "2.7.22" % "test"
import com.typesafe.sbt.SbtScalariform
import scalariform.formatter.preferences._
import com.typesafe.sbt.SbtScalariform.ScalariformKeys
SbtScalariform.defaultScalariformSettings
ScalariformKeys.preferences := ScalariformKeys.preferences.value
.setPreference(AlignSingleLineCaseStatements, true)
.setPreference(DoubleIndentClassDeclaration, true)
.setPreference(AlignParameters, true)
scalariformSettings
//-----------

View File

@ -1,6 +1,8 @@
addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2")
addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
//addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.2.0")

3
akka-bbb-apps/run.sh Executable file
View File

@ -0,0 +1,3 @@
sbt clean
sbt run

View File

@ -1,32 +1,39 @@
import org.bigbluebutton.core.apps.BreakoutRoomModel
import org.bigbluebutton.core.apps.BreakoutRoomApp
import com.google.gson.Gson
import org.bigbluebutton.messages.BreakoutRoomJoinURL
object BreakoutRoom {
val breakoutModel = new BreakoutRoomModel //> breakoutModel : org.bigbluebutton.core.apps.BreakoutRoomModel = org.bigblue
//| button.core.apps.BreakoutRoomModel@721d4bd9
val gson = new Gson //> gson : com.google.gson.Gson = {serializeNulls:falsefactories:[Factory[typeH
//| ierarchy=com.google.gson.JsonElement,adapter=com.google.gson.internal.bind.T
//| ypeAdapters$29@6979e8cb], com.google.gson.internal.bind.ObjectTypeAdapter$1@
//| 763d9750, com.google.gson.internal.Excluder@5c0369c4, Factory[type=java.lang
//| .String,adapter=com.google.gson.internal.bind.TypeAdapters$16@2be94b0f], Fac
//| tory[type=java.lang.Integer+int,adapter=com.google.gson.internal.bind.TypeAd
//| apters$7@d70c109], Factory[type=java.lang.Boolean+boolean,adapter=com.google
//| .gson.internal.bind.TypeAdapters$3@17ed40e0], Factory[type=java.lang.Byte+by
//| te,adapter=com.google.gson.internal.bind.TypeAdapters$5@50675690], Factory[t
//| ype=java.lang.Short+short,adapter=com.google.gson.internal.bind.TypeAdapters
//| $6@31b7dea0], Factory[type=java.lang.Long+long,adapter=com.google.gson.inter
//| nal.bind.TypeAdapters$11@3ac42916], Factory[type=java.lang.Double+double,ada
//| pter=com.google.gson.Gso
//| Output exceeds cutoff limit.
breakoutModel.createBreakoutRoom("1", "Room 1", "voice-1", Vector("user-1"), "default.pdf")
//> res0: org.bigbluebutton.core.apps.BreakoutRoom = BreakoutRoom(1,Room 1,voice
//| -1,Vector(user-1),Vector(),default.pdf)
breakoutModel.createBreakoutRoom("2", "Room 2", "voice-2", Vector("user-2"), "default.pdf")
//> res1: org.bigbluebutton.core.apps.BreakoutRoom = BreakoutRoom(2,Room 2,voice
//| -2,Vector(user-2),Vector(),default.pdf)
breakoutModel.getAssignedUsers("1") //> res2: Option[Vector[String]] = Some(Vector(user-1))
breakoutModel.getAssignedUsers("2") //> res3: Option[Vector[String]] = Some(Vector(user-2))
val string = "{\"payload\":{\"redirectJoinUrl\":\"alink\",\"breakoutMeetingId\":\"4455e780b6f62cd5fcf09367aef62d9bc5108375-1479728671031\",\"noRedirectJoinUrl\":\"http://bbb.riadvice.com/bigbluebutton/api/join?fullName\u003dOpera\u0026isBreakout\u003dtrue\u0026meetingID\u003d4455e780b6f62cd5fcf09367aef62d9bc5108375-1479728671031\u0026password\u003dmp\u0026redirect\u003dfalse\u0026userID\u003d6pt0vfeaxdze_1-1\u0026checksum\u003d51c4a1398b88170c25f1a71521bca604e784ab23\",\"parentMeetingId\":\"183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1479728593178\",\"userId\":\"6pt0vfeaxdze_1\"},\"header\":{\"name\":\"BreakoutRoomJoinURL\",\"version\":\"0.0.1\",\"current_time\":1479728673586,\"timestamp\":8549632}}"
//> string : String = {"payload":{"redirectJoinUrl":"alink","breakoutMeetingId"
//| :"4455e780b6f62cd5fcf09367aef62d9bc5108375-1479728671031","noRedirectJoinUrl
//| ":"http://bbb.riadvice.com/bigbluebutton/api/join?fullName=Opera&isBreakout=
//| true&meetingID=4455e780b6f62cd5fcf09367aef62d9bc5108375-1479728671031&passwo
//| rd=mp&redirect=false&userID=6pt0vfeaxdze_1-1&checksum=51c4a1398b88170c25f1a7
//| 1521bca604e784ab23","parentMeetingId":"183f0bf3a0982a127bdb8161e0c44eb696b3e
//| 75c-1479728593178","userId":"6pt0vfeaxdze_1"},"header":{"name":"BreakoutRoom
//| JoinURL","version":"0.0.1","current_time":1479728673586,"timestamp":8549632}
//| }
val brjum: BreakoutRoomJoinURL = gson.fromJson(string, classOf[BreakoutRoomJoinURL])
//> brjum : org.bigbluebutton.messages.BreakoutRoomJoinURL = org.bigbluebutton.
//| messages.BreakoutRoomJoinURL@3327bd23
var breakoutRoomId = "1" //> breakoutRoomId : String = 1
breakoutModel.getAssignedUsers(breakoutRoomId) foreach { users =>
users.foreach { u =>
println(Vector(u, breakoutRoomId))
} //> Vector(user-1, 1)
}
breakoutRoomId = "2"
breakoutModel.getAssignedUsers(breakoutRoomId) foreach { users =>
users.foreach { u =>
println(Vector(u, breakoutRoomId))
} //> Vector(user-2, 2)
}
println(brjum.payload.userId) //> 6pt0vfeaxdze_1
println(brjum.payload.parentMeetingId) //> 183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1479728593178
println(brjum.payload.breakoutMeetingId) //> 4455e780b6f62cd5fcf09367aef62d9bc5108375-1479728671031
println(brjum.payload.redirectJoinURL) //> null
println(brjum.payload.noRedirectJoinURL) //> null
}

View File

@ -0,0 +1,9 @@
import scala.collection.mutable
object Collections {
val messages = new mutable.Queue[String]()
messages += "foo"
messages += "bar"
messages += "baz"
messages.foreach(f => println(f))
}

View File

@ -1,23 +1,23 @@
import scala.collection.immutable.StringOps
import java.net.URLEncoder
import scala.collection._
object Test2 {
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
println("Welcome to the Scala worksheet") //> Welcome to the Scala worksheet
val userId = new StringOps("abc_12") //> userId : scala.collection.immutable.StringOps = abc_12
val s2 = userId.split('_') //> s2 : Array[String] = Array(abc, 12)
val s1 = if (s2.length == 2) s2(0) else userId //> s1 : Comparable[String] = abc
val userId = new StringOps("abc_12") //> userId : scala.collection.immutable.StringOps = abc_12
val s2 = userId.split('_') //> s2 : Array[String] = Array(abc, 12)
val s1 = if (s2.length == 2) s2(0) else userId //> s1 : Comparable[String] = abc
def sortParam(params: mutable.Map[String, String]):SortedSet[String] = {
collection.immutable.SortedSet[String]() ++ params.keySet
} //> sortParam: (params: scala.collection.mutable.Map[String,String])scala.collec
//| tion.SortedSet[String]
//| tion.SortedSet[String]
def createBaseString(params: mutable.Map[String, String]): String = {
val csbuf = new StringBuffer()
var keys = sortParam(params)
var first = true;
for (key <- keys) {
for (value <- params.get(key)) {
@ -26,42 +26,52 @@ object Test2 {
} else {
csbuf.append("&");
}
csbuf.append(key);
csbuf.append("=");
csbuf.append(value);
}
}
return csbuf.toString();
} //> createBaseString: (params: scala.collection.mutable.Map[String,String])Strin
//| g
//| g
def urlEncode(s: String): String = {
URLEncoder.encode(s, "UTF-8");
} //> urlEncode: (s: String)String
} //> urlEncode: (s: String)String
val baseString = "fullName=User+4621018&isBreakout=true&meetingID=random-1853792&password=mp&redirect=true"
//> baseString : String = fullName=User+4621018&isBreakout=true&meetingID=rand
//| om-1853792&password=mp&redirect=true
//| om-1853792&password=mp&redirect=true
val params = new collection.mutable.HashMap[String, String]
//> params : scala.collection.mutable.HashMap[String,String] = Map()
//> params : scala.collection.mutable.HashMap[String,String] = Map()
params += "fullName" -> urlEncode("User 4621018")
//> res0: Test2.params.type = Map(fullName -> User+4621018)
//> res0: Test2.params.type = Map(fullName -> User+4621018)
params += "isBreakout" -> urlEncode("true") //> res1: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true)
//|
//|
params += "meetingID" -> urlEncode("random-1853792")
//> res2: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true,
//| meetingID -> random-1853792)
//| meetingID -> random-1853792)
params += "password" -> urlEncode("mp") //> res3: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true,
//| meetingID -> random-1853792, password -> mp)
//| meetingID -> random-1853792, password -> mp)
params += "redirect" -> urlEncode("true") //> res4: Test2.params.type = Map(fullName -> User+4621018, isBreakout -> true,
//| meetingID -> random-1853792, redirect -> true, password -> mp)
//| meetingID -> random-1853792, redirect -> true, password -> mp)
val keys = sortParam(params) //> keys : scala.collection.SortedSet[String] = TreeSet(fullName, isBreakout,
//| meetingID, password, redirect)
//| meetingID, password, redirect)
val result = createBaseString(params) //> result : String = fullName=User+4621018&isBreakout=true&meetingID=random-1
//| 853792&password=mp&redirect=true
//| 853792&password=mp&redirect=true
val between = Set("xab", "bc")
val u2 = Set("bc", "xab")
val u3 = u2 + "zxc"
val foo = between subsetOf(u2)
val id = between.toSeq.sorted.mkString("-")
}

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,9 @@
package org.bigbluebutton.core.api;
import java.util.Map;
import org.bigbluebutton.common.messages.*;
public interface IBigBlueButtonInGW {
void handleJsonMessage(String json);
void handleBigBlueButtonMessage(IBigBlueButtonMessage message);
void isAliveAudit(String aliveID);
@ -15,105 +13,11 @@ public interface IBigBlueButtonInGW {
void destroyMeeting(String meetingID);
void getAllMeetings(String meetingID);
void lockSettings(String meetingID, Boolean locked, Map<String, Boolean> lockSettigs);
void activityResponse(String meetingID);
// Polling
void votePoll(String meetingId, String userId, String pollId, Integer questionId, Integer answerId);
void startPoll(String meetingId, String requesterId, String pollId, String pollType);
void stopPoll(String meetingId, String userId, String pollId);
void showPollResult(String meetingId, String requesterId, String pollId, Boolean show);
// Lock
void initLockSettings(String meetingID, Map<String, Boolean> settings);
void sendLockSettings(String meetingID, String userId, Map<String, Boolean> settings);
void getLockSettings(String meetingId, String userId);
void lockUser(String meetingId, String requesterID, boolean lock, String internalUserID);
// Users
void validateAuthToken(String meetingId, String userId, String token, String correlationId, String sessionId);
void registerUser(String roomName, String userid, String username, String role, String externUserID, String authToken, String avatarURL);
void userEmojiStatus(String meetingId, String userId, String emojiStatus);
void shareWebcam(String meetingId, String userId, String stream);
void unshareWebcam(String meetingId, String userId, String stream);
void setUserStatus(String meetingID, String userID, String status, Object value);
void getUsers(String meetingID, String requesterID);
void userLeft(String meetingID, String userID, String sessionId);
void userJoin(String meetingID, String userID, String authToken);
void getCurrentPresenter(String meetingID, String requesterID);
void checkIfAllowedToShareDesktop(String meetingID, String userID);
void assignPresenter(String meetingID, String newPresenterID, String newPresenterName, String assignedBy);
void setRecordingStatus(String meetingId, String userId, Boolean recording);
void getRecordingStatus(String meetingId, String userId);
void userConnectedToGlobalAudio(String voiceConf, String userid, String name);
void userDisconnectedFromGlobalAudio(String voiceConf, String userid, String name);
// Voice
void initAudioSettings(String meetingID, String requesterID, Boolean muted);
void muteAllExceptPresenter(String meetingID, String requesterID, Boolean mute);
void muteAllUsers(String meetingID, String requesterID, Boolean mute);
void isMeetingMuted(String meetingID, String requesterID);
void muteUser(String meetingID, String requesterID, String userID, Boolean mute);
void lockMuteUser(String meetingID, String requesterID, String userID, Boolean lock);
void ejectUserFromVoice(String meetingID, String userId, String ejectedBy);
void ejectUserFromMeeting(String meetingId, String userId, String ejectedBy);
void voiceUserJoined(String voiceConfId, String voiceUserId, String userId, String callerIdName,
String callerIdNum, Boolean muted, String avatarURL, Boolean talking);
void voiceUserLeft(String meetingId, String userId);
void voiceUserLocked(String meetingId, String userId, Boolean locked);
void voiceUserMuted(String meetingId, String userId, Boolean muted);
void voiceUserTalking(String meetingId, String userId, Boolean talking);
void voiceRecording(String meetingId, String recordingFile,
String timestamp, Boolean recording);
// Presentation
void clear(String meetingID);
void removePresentation(String meetingID, String presentationID);
void getPresentationInfo(String meetingID, String requesterID, String replyTo);
void sendCursorUpdate(String meetingID, double xPercent, double yPercent);
void resizeAndMoveSlide(String meetingID, double xOffset, double yOffset, double widthRatio, double heightRatio);
void gotoSlide(String meetingID, String page);
void sharePresentation(String meetingID, String presentationID, boolean share);
void getSlideInfo(String meetingID, String requesterID, String replyTo);
void sendConversionUpdate(String messageKey, String meetingId,
String code, String presId, String presName);
void sendPageCountError(String messageKey, String meetingId,
String code, String presId, int numberOfPages,
int maxNumberPages, String presName);
void sendSlideGenerated(String messageKey, String meetingId,
String code, String presId, int numberOfPages,
int pagesCompleted, String presName);
void sendConversionCompleted(String messageKey, String meetingId,
String code, String presId, int numPages, String presName, String presBaseUrl);
// Layout
void getCurrentLayout(String meetingID, String requesterID);
void broadcastLayout(String meetingID, String requesterID, String layout);
void lockLayout(String meetingID, String setById,
boolean lock, boolean viewersOnly,
String layout);
// Chat
void getChatHistory(String meetingID, String requesterID, String replyTo);
void sendPublicMessage(String meetingID, String requesterID, Map<String, String> message);
void sendPrivateMessage(String meetingID, String requesterID, Map<String, String> message);
// Whiteboard
void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> annotation);
void requestWhiteboardAnnotationHistory(String meetingID, String requesterID, String whiteboardId, String replyTo);
void clearWhiteboard(String meetingID, String requesterID, String whiteboardId);
void undoWhiteboard(String meetingID, String requesterID, String whiteboardId);
void enableWhiteboard(String meetingID, String requesterID, Boolean enable);
void isWhiteboardEnabled(String meetingID, String requesterID, String replyTo);
// Caption
void sendCaptionHistory(String meetingID, String requesterID);
void updateCaptionOwner(String meetingID, String locale, String localeCode, String ownerID);
void editCaptionHistory(String meetingID, String userID, Integer startIndex, Integer endIndex, String locale, String localeCode, String text);
// DeskShare
void deskShareStarted(String confId, String callerId, String callerIdName);
void deskShareStopped(String conferenceName, String callerId, String callerIdName);

View File

@ -1,66 +0,0 @@
package org.bigbluebutton.core.api;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class RedisLpushDispatcher implements IDispatcher {
private static final int NTHREADS = 1;
private static final Executor exec = Executors.newFixedThreadPool(NTHREADS);
private static final String BBBMESSAGES = "bbb:meeting:messages";
private BlockingQueue<String> messages;
private volatile boolean dispatchEvents = false;
private JedisPool redisPool;
public RedisLpushDispatcher() {
messages = new LinkedBlockingQueue<String>();
}
@Override
public void dispatch(String jsonMessage) {
messages.offer(jsonMessage);
}
private void saveMessage(String msg) {
Jedis jedis = redisPool.getResource();
try {
jedis.lpush(BBBMESSAGES, msg);
} finally {
redisPool.returnResource(jedis);
}
}
public void start() {
dispatchEvents = true;
Runnable sender = new Runnable() {
public void run() {
while (dispatchEvents) {
String message;
try {
message = messages.take();
saveMessage(message);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
exec.execute(sender);
}
public void stop() {
dispatchEvents = false;
}
public void setRedisPool(JedisPool redisPool) {
this.redisPool = redisPool;
}
}

View File

@ -1,44 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.EditCaptionHistoryMessage;
import org.bigbluebutton.common.messages.SendCaptionHistoryRequestMessage;
import org.bigbluebutton.common.messages.UpdateCaptionOwnerMessage;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class CaptionMessageReceiver implements MessageHandler{
private IBigBlueButtonInGW bbbGW;
public CaptionMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_CAPTION_CHANNEL)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (SendCaptionHistoryRequestMessage.SEND_CAPTION_HISTORY_REQUEST.equals(messageName)){
SendCaptionHistoryRequestMessage msg = SendCaptionHistoryRequestMessage.fromJson(message);
bbbGW.sendCaptionHistory(msg.meetingID, msg.requesterID);
} else if (UpdateCaptionOwnerMessage.UPDATE_CAPTION_OWNER.equals(messageName)) {
UpdateCaptionOwnerMessage msg = UpdateCaptionOwnerMessage.fromJson(message);
bbbGW.updateCaptionOwner(msg.meetingID, msg.locale, msg.localeCode, msg.ownerID);
} else if (EditCaptionHistoryMessage.EDIT_CAPTION_HISTORY.equals(messageName)) {
EditCaptionHistoryMessage msg = EditCaptionHistoryMessage.fromJson(message);
bbbGW.editCaptionHistory(msg.meetingID, msg.userID, msg.startIndex, msg.endIndex, msg.locale, msg.localeCode, msg.text);
}
}
}
}
}
}

View File

@ -1,44 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.GetChatHistoryRequestMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.SendPrivateChatMessage;
import org.bigbluebutton.common.messages.SendPublicChatMessage;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class ChatMessageReceiver implements MessageHandler{
private IBigBlueButtonInGW bbbGW;
public ChatMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_CHAT_CHANNEL)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (GetChatHistoryRequestMessage.GET_CHAT_HISTORY_REQUEST.equals(messageName)) {
GetChatHistoryRequestMessage msg = GetChatHistoryRequestMessage.fromJson(message);
bbbGW.getChatHistory(msg.meetingId, msg.requesterId, msg.replyTo);
} else if (SendPublicChatMessage.SEND_PUBLIC_CHAT_MESSAGE.equals(messageName)){
SendPublicChatMessage msg = SendPublicChatMessage.fromJson(message);
bbbGW.sendPublicMessage(msg.meetingId, msg.requesterId, msg.messageInfo);
} else if (SendPrivateChatMessage.SEND_PRIVATE_CHAT_MESSAGE.equals(messageName)){
SendPrivateChatMessage msg = SendPrivateChatMessage.fromJson(message);
bbbGW.sendPrivateMessage(msg.meetingId, msg.requesterId, msg.messageInfo);
}
}
}
}
}
}

View File

@ -1,61 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class ConversionUpdatesProcessor {
private IBigBlueButtonInGW bbbInGW;
public ConversionUpdatesProcessor(IBigBlueButtonInGW bbbInGW) {
this.bbbInGW = bbbInGW;
}
public void sendConversionUpdate(String messageKey, String conference,
String code, String presId, String presName) {
bbbInGW.sendConversionUpdate(messageKey, conference,
code, presId, presName);
}
public void sendPageCountError(String messageKey, String conference,
String code, String presId, int numberOfPages,
int maxNumberPages, String presName) {
bbbInGW.sendPageCountError(messageKey, conference, code, presId, numberOfPages,
maxNumberPages, presName);
}
public void sendSlideGenerated(String messageKey, String conference,
String code, String presId, int numberOfPages,
int pagesCompleted, String presName) {
bbbInGW.sendSlideGenerated(messageKey, conference,
code, presId, numberOfPages, pagesCompleted, presName);
}
public void sendConversionCompleted(String messageKey, String conference,
String code, String presId, Integer numberOfPages, String presName,
String presBaseUrl) {
bbbInGW.sendConversionCompleted(messageKey, conference,
code, presId, numberOfPages, presName, presBaseUrl);
}
public void setBigBlueButtonInGW(IBigBlueButtonInGW inGW) {
bbbInGW = inGW;
}
}

View File

@ -1,59 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.bigbluebutton.common.messages.DeskShareStartedEventMessage;
import org.bigbluebutton.common.messages.DeskShareStoppedEventMessage;
import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStartedEventMessage;
import org.bigbluebutton.common.messages.DeskShareRTMPBroadcastStoppedEventMessage;
import org.bigbluebutton.common.messages.DeskShareGetInfoRequestMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class DeskShareMessageReceiver implements MessageHandler {
private IBigBlueButtonInGW bbbGW;
private static final Logger log = LoggerFactory.getLogger(DeskShareMessageReceiver.class);
public DeskShareMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.FROM_VOICE_CONF_SYSTEM_CHAN)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (DeskShareStartedEventMessage.DESKSHARE_STARTED_MESSAGE.equals(messageName)) {
DeskShareStartedEventMessage msg = DeskShareStartedEventMessage.fromJson(message);
log.info("^^^^^^^DESKSHARE STARTED^^^^^^");
bbbGW.deskShareStarted(msg.conferenceName, msg.callerId, msg.callerIdName);
} else if (DeskShareStoppedEventMessage.DESK_SHARE_STOPPED_MESSAGE.equals(messageName)) {
DeskShareStoppedEventMessage msg = DeskShareStoppedEventMessage.fromJson(message);
log.info("^^^^^^^DESKSHARE STOPPED^^^^^^");
bbbGW.deskShareStopped(msg.conferenceName, msg.callerId, msg.callerIdName);
} else if (DeskShareRTMPBroadcastStartedEventMessage.DESKSHARE_RTMP_BROADCAST_STARTED_MESSAGE.equals(messageName)) {
log.info("^^^^^^^DESKSHARE_RTMP_BROADCAST_STARTED_MESSAGE^^^^^^");
DeskShareRTMPBroadcastStartedEventMessage msg = DeskShareRTMPBroadcastStartedEventMessage.fromJson(message);
bbbGW.deskShareRTMPBroadcastStarted(msg.conferenceName, msg.streamname, msg.vw, msg.vh, msg.timestamp);
} else if (DeskShareRTMPBroadcastStoppedEventMessage.DESKSHARE_RTMP_BROADCAST_STOPPED_MESSAGE.equals(messageName)) {
log.info("^^^^^^^DESKSHARE_RTMP_BROADCAST_STOPPED_MESSAGE^^^^^^");
DeskShareRTMPBroadcastStoppedEventMessage msg = DeskShareRTMPBroadcastStoppedEventMessage.fromJson(message);
bbbGW.deskShareRTMPBroadcastStopped(msg.conferenceName, msg.streamname, msg.vw, msg.vh, msg.timestamp);
} else if (DeskShareGetInfoRequestMessage.GET_DESKTOP_SHARE_GET_INFO_REQUEST.equals(messageName)) {
log.info("^^^^^^^GET_DESKTOP_SHARE_INFO_REQUEST^^^^^^");
DeskShareGetInfoRequestMessage msg = DeskShareGetInfoRequestMessage.fromJson(message);
bbbGW.deskShareGetInfoRequest(msg.meetingId, msg.requesterId, msg.replyTo);
}
}
}
}
}
}

View File

@ -1,45 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.GetLockSettingsMessage;
import org.bigbluebutton.common.messages.LockUserMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.SendLockSettingsMessage;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
public class LockMessageReceiver implements MessageHandler {
private IBigBlueButtonInGW bbbGW;
public LockMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_MEETING_CHANNEL)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (GetLockSettingsMessage.GET_LOCK_SETTINGS.equals(messageName)) {
GetLockSettingsMessage msg = GetLockSettingsMessage.fromJson(message);
bbbGW.getLockSettings(msg.meetingId, msg.userId);
} else if(LockUserMessage.LOCK_USER.equals(messageName)) {
LockUserMessage msg = LockUserMessage.fromJson(message);
bbbGW.lockUser(msg.meetingId, msg.requesterId, msg.lock, msg.internalUserId);
} else if(SendLockSettingsMessage.SEND_LOCK_SETTINGS.equals(messageName)) {
SendLockSettingsMessage msg = SendLockSettingsMessage.fromJson(message);
bbbGW.sendLockSettings(msg.meetingId, msg.userId, msg.newSettings);
}
}
}
}
}
}

View File

@ -3,6 +3,7 @@ package org.bigbluebutton.core.pubsub.receivers;
import java.util.HashMap;
import java.util.Map;
import org.bigbluebutton.common.messages.ActivityResponseMessage;
import org.bigbluebutton.common.messages.DestroyMeetingMessage;
import org.bigbluebutton.common.messages.EndMeetingMessage;
import org.bigbluebutton.common.messages.GetAllMeetingsRequest;
@ -11,10 +12,7 @@ import org.bigbluebutton.common.messages.KeepAliveMessage;
import org.bigbluebutton.common.messages.MessageFromJsonConverter;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.PubSubPingMessage;
import org.bigbluebutton.common.messages.RegisterUserMessage;
import org.bigbluebutton.common.messages.UserConnectedToGlobalAudio;
import org.bigbluebutton.common.messages.UserDisconnectedFromGlobalAudio;
import org.bigbluebutton.common.messages.ValidateAuthTokenMessage;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import org.bigbluebutton.messages.CreateMeetingRequest;
import org.slf4j.Logger;
@ -35,7 +33,6 @@ public class MeetingMessageReceiver implements MessageHandler {
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_MEETING_CHANNEL)) {
System.out.println("Meeting message: " + channel + " " + message);
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
@ -45,8 +42,7 @@ public class MeetingMessageReceiver implements MessageHandler {
String messageName = header.get("name").getAsString();
if (CreateMeetingRequest.NAME.equals(messageName)) {
Gson gson = new Gson();
CreateMeetingRequest msg = gson.fromJson(message,
CreateMeetingRequest.class);
CreateMeetingRequest msg = gson.fromJson(message, CreateMeetingRequest.class);
bbbGW.handleBigBlueButtonMessage(msg);
}
}
@ -58,52 +54,14 @@ public class MeetingMessageReceiver implements MessageHandler {
if (msg instanceof EndMeetingMessage) {
EndMeetingMessage emm = (EndMeetingMessage) msg;
bbbGW.endMeeting(emm.meetingId);
} else if (msg instanceof RegisterUserMessage) {
RegisterUserMessage rum = (RegisterUserMessage) msg;
bbbGW.registerUser(rum.meetingID, rum.internalUserId, rum.fullname, rum.role, rum.externUserID, rum.authToken, rum.avatarURL);
} else if (msg instanceof DestroyMeetingMessage) {
DestroyMeetingMessage dmm = (DestroyMeetingMessage) msg;
bbbGW.destroyMeeting(dmm.meetingId);
} else if (msg instanceof ValidateAuthTokenMessage) {
ValidateAuthTokenMessage vam = (ValidateAuthTokenMessage) msg;
String sessionId = "tobeimplemented";
bbbGW.validateAuthToken(vam.meetingId, vam.userId, vam.token, vam.replyTo, sessionId);
} else if (msg instanceof UserConnectedToGlobalAudio) {
UserConnectedToGlobalAudio ustga = (UserConnectedToGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", ustga.voiceConf);
logData.put("userId", ustga.userid);
logData.put("username", ustga.name);
logData.put("event", "user_connected_to_global_audio");
logData.put("description", "User connected to global audio.");
/*
Gson gson = new Gson();
String logStr = gson.toJson(logData);
System.out.println("User connected to global audio: data={}", logStr);
*/
bbbGW.userConnectedToGlobalAudio(ustga.voiceConf, ustga.userid, ustga.name);
} else if (msg instanceof UserDisconnectedFromGlobalAudio) {
UserDisconnectedFromGlobalAudio udfga = (UserDisconnectedFromGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", udfga.voiceConf);
logData.put("userId", udfga.userid);
logData.put("username", udfga.name);
logData.put("event", "user_disconnected_from_global_audio");
logData.put("description", "User disconnected from global audio.");
/*
Gson gson = new Gson();
String logStr = gson.toJson(logData);
System.out.println("User disconnected from global audio: data={}", logStr);
*/
bbbGW.userDisconnectedFromGlobalAudio(udfga.voiceConf, udfga.userid, udfga.name);
}
else if (msg instanceof GetAllMeetingsRequest) {
GetAllMeetingsRequest gamr = (GetAllMeetingsRequest) msg;
bbbGW.getAllMeetings("no_need_of_a_meeting_id");
} else if (msg instanceof ActivityResponseMessage) {
ActivityResponseMessage arm = (ActivityResponseMessage) msg;
bbbGW.activityResponse(arm.meetingId);
} else {
System.out.println("Unknown message: [" + message + "]");
}

View File

@ -1,53 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.*;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PollingMessageReceiver implements MessageHandler{
private static final Logger log = LoggerFactory.getLogger(PollingMessageReceiver.class);
private IBigBlueButtonInGW bbbGW;
public PollingMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_POLLING_CHANNEL)) {
log.debug("Polling message: " + channel + " " + message);
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (VotePollUserRequestMessage.VOTE_POLL_REQUEST.equals(messageName)) {
VotePollUserRequestMessage msg = VotePollUserRequestMessage.fromJson(message);
bbbGW.votePoll(msg.meetingId, msg.userId, msg.pollId, msg.questionId, msg.answerId);
} else if (StartPollRequestMessage.START_POLL_REQUEST.equals(messageName)){
log.debug("Received StartPollRequest message");
StartPollRequestMessage msg = StartPollRequestMessage.fromJson(message);
bbbGW.startPoll(msg.meetingId, msg.requesterId, msg.pollId, msg.pollType);
} else if (StopPollRequestMessage.STOP_POLL_REQUEST.equals(messageName)){
StopPollRequestMessage msg = StopPollRequestMessage.fromJson(message);
bbbGW.stopPoll(msg.meetingId, msg.requesterId, msg.pollId);
} else if (ShowPollResultRequestMessage.SHOW_POLL_RESULT_REQUEST.equals(messageName)){
ShowPollResultRequestMessage msg = ShowPollResultRequestMessage.fromJson(message);
bbbGW.showPollResult(msg.meetingId, msg.requesterId, msg.pollId, msg.show);
} else if (StartCustomPollRequestMessage.START_CUSTOM_POLL_REQUEST.equals(messageName)){
Gson gson = new Gson();
StartCustomPollRequestMessage msg = gson.fromJson(message, StartCustomPollRequestMessage.class);
bbbGW.handleBigBlueButtonMessage(msg);
}
}
}
}
}
}

View File

@ -1,181 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import java.util.HashMap;
import org.bigbluebutton.common.messages.GetPresentationInfoMessage;
import org.bigbluebutton.common.messages.GetSlideInfoMessage;
import org.bigbluebutton.common.messages.GoToSlideMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.RemovePresentationMessage;
import org.bigbluebutton.common.messages.ResizeAndMoveSlideMessage;
import org.bigbluebutton.common.messages.SendConversionCompletedMessage;
import org.bigbluebutton.common.messages.SendConversionUpdateMessage;
import org.bigbluebutton.common.messages.SendCursorUpdateMessage;
import org.bigbluebutton.common.messages.SendPageCountErrorMessage;
import org.bigbluebutton.common.messages.SendSlideGeneratedMessage;
import org.bigbluebutton.common.messages.SharePresentationMessage;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
public class PresentationMessageListener implements MessageHandler {
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 OFFICE_DOC_CONVERSION_INVALID_KEY = "OFFICE_DOC_CONVERSION_INVALID";
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";
private ConversionUpdatesProcessor conversionUpdatesProcessor;
private IBigBlueButtonInGW bbbInGW;
public PresentationMessageListener(IBigBlueButtonInGW inGW) {
bbbInGW = inGW;
conversionUpdatesProcessor = new ConversionUpdatesProcessor(bbbInGW);
}
private void sendConversionUpdate(String messageKey, String conference,
String code, String presId, String filename) {
conversionUpdatesProcessor.sendConversionUpdate(messageKey, conference,
code, presId, filename);
}
public void sendPageCountError(String messageKey, String conference,
String code, String presId, Integer numberOfPages,
Integer maxNumberPages, String filename) {
conversionUpdatesProcessor.sendPageCountError(messageKey, conference,
code, presId, numberOfPages,
maxNumberPages, filename);
}
private void sendSlideGenerated(String messageKey, String conference,
String code, String presId, Integer numberOfPages,
Integer pagesCompleted, String filename) {
conversionUpdatesProcessor.sendSlideGenerated(messageKey, conference,
code, presId, numberOfPages,
pagesCompleted, filename);
}
private void sendConversionCompleted(String messageKey, String conference,
String code, String presId, Integer numberOfPages,
String filename, String presBaseUrl) {
conversionUpdatesProcessor.sendConversionCompleted(messageKey, conference,
code, presId, numberOfPages, filename, presBaseUrl);
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_PRESENTATION_CHANNEL)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (SendConversionUpdateMessage.SEND_CONVERSION_UPDATE.equals(messageName)) {
SendConversionUpdateMessage msg = SendConversionUpdateMessage.fromJson(message);
// sendConversionUpdate(msg.messageKey, msg.meetingId, msg.code,
// msg.presId, msg.presName);
bbbInGW.sendConversionUpdate(msg.messageKey, msg.meetingId,
msg.code, msg.presId, msg.presName);
} else if (ResizeAndMoveSlideMessage.RESIZE_AND_MOVE_SLIDE.equals(messageName)) {
ResizeAndMoveSlideMessage msg = ResizeAndMoveSlideMessage.fromJson(message);
bbbInGW.resizeAndMoveSlide(msg.meetingId, msg.xOffset, msg.yOffset,
msg.widthRatio, msg.heightRatio);
} else if (GetPresentationInfoMessage.GET_PRESENTATION_INFO.equals(messageName)) {
GetPresentationInfoMessage msg = GetPresentationInfoMessage.fromJson(message);
bbbInGW.getPresentationInfo(msg.meetingId, msg.requesterId, msg.replyTo);
} else if (SendConversionCompletedMessage.SEND_CONVERSION_COMPLETED.equals(messageName)) {
SendConversionCompletedMessage msg = SendConversionCompletedMessage.fromJson(message);
// sendConversionCompleted(msg.messageKey, msg.meetingId, msg.code,
// msg.presId, msg.numPages, msg.presName, msg.presBaseUrl);
bbbInGW.sendConversionCompleted(msg.messageKey, msg.meetingId, msg.code,
msg.presId, msg.numPages, msg.presName, msg.presBaseUrl);
} else if (SendPageCountErrorMessage.SEND_PAGE_COUNT_ERROR.equals(messageName)) {
SendPageCountErrorMessage msg = SendPageCountErrorMessage.fromJson(message);
// sendPageCountError(msg.messageKey, msg.meetingId, msg.code,
// msg.presId, msg.numberOfPages, msg.maxNumberPages, msg.presName);
bbbInGW.sendPageCountError(msg.messageKey, msg.meetingId, msg.code,
msg.presId, msg.numberOfPages, msg.maxNumberPages, msg.presName);
} else if (GoToSlideMessage.GO_TO_SLIDE.equals(messageName)) {
GoToSlideMessage msg = GoToSlideMessage.fromJson(message);
bbbInGW.gotoSlide(msg.meetingId, msg.page);
} else if (RemovePresentationMessage.REMOVE_PRESENTATION.equals(messageName)) {
RemovePresentationMessage msg = RemovePresentationMessage.fromJson(message);
bbbInGW.removePresentation(msg.meetingId, msg.presentationId);
} else if (SendCursorUpdateMessage.SEND_CURSOR_UPDATE.equals(messageName)) {
SendCursorUpdateMessage msg = SendCursorUpdateMessage.fromJson(message);
bbbInGW.sendCursorUpdate(msg.meetingId, msg.xPercent, msg.yPercent);
} else if (SharePresentationMessage.SHARE_PRESENTATION.equals(messageName)) {
SharePresentationMessage msg = SharePresentationMessage.fromJson(message);
bbbInGW.sharePresentation(msg.meetingId, msg.presentationId, msg.share);
} else if (GetSlideInfoMessage.GET_SLIDE_INFO.equals(messageName)) {
GetSlideInfoMessage msg = GetSlideInfoMessage.fromJson(message);
bbbInGW.getSlideInfo(msg.meetingId, msg.requesterId, msg.replyTo);
} else if (SendSlideGeneratedMessage.SEND_SLIDE_GENERATED.equals(messageName)) {
SendSlideGeneratedMessage msg = SendSlideGeneratedMessage.fromJson(message);
bbbInGW.sendSlideGenerated(msg.messageKey, msg.meetingId, msg.code,
msg.presId, msg.numberOfPages, msg.pagesCompleted, msg.presName);
}
}
}
else {
HashMap<String,String> map = new Gson().fromJson(message, new TypeToken<HashMap<String, String>>() {}.getType());
String code = (String) map.get("returnCode");
String presId = (String) map.get("presentationId");
String filename = (String) map.get("filename");
String conference = (String) map.get("conference");
String messageKey = (String) map.get("messageKey");
if (messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_SUCCESS_KEY) ||
messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_FAILED_KEY) ||
messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_INVALID_KEY) ||
messageKey.equalsIgnoreCase(SUPPORTED_DOCUMENT_KEY) ||
messageKey.equalsIgnoreCase(UNSUPPORTED_DOCUMENT_KEY) ||
messageKey.equalsIgnoreCase(GENERATING_THUMBNAIL_KEY) ||
messageKey.equalsIgnoreCase(GENERATED_THUMBNAIL_KEY) ||
messageKey.equalsIgnoreCase(PAGE_COUNT_FAILED_KEY)){
sendConversionUpdate(messageKey, conference, code, presId, filename);
} else if(messageKey.equalsIgnoreCase(PAGE_COUNT_EXCEEDED_KEY)){
Integer numberOfPages = new Integer((String) map.get("numberOfPages"));
Integer maxNumberPages = new Integer((String) map.get("maxNumberPages"));
sendPageCountError(messageKey, conference, code,
presId, numberOfPages, maxNumberPages, filename);
} else if(messageKey.equalsIgnoreCase(GENERATED_SLIDE_KEY)){
Integer numberOfPages = new Integer((String) map.get("numberOfPages"));
Integer pagesCompleted = new Integer((String) map.get("pagesCompleted"));
sendSlideGenerated(messageKey, conference, code,
presId, numberOfPages, pagesCompleted, filename);
} else if(messageKey.equalsIgnoreCase(CONVERSION_COMPLETED_KEY)){
Integer numberOfPages = new Integer((String) map.get("numberOfPages"));
String presBaseUrl = (String) map.get("presentationBaseUrl");
sendConversionCompleted(messageKey, conference, code,
presId, numberOfPages, filename, presBaseUrl);
}
}
}
}
}

View File

@ -1,12 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
public class PreuploadedPresentation {
public final String id;
public final int numPages;
public PreuploadedPresentation(String id, int numPages) {
this.id = id;
this.numPages = numPages;
}
}

View File

@ -31,32 +31,11 @@ public class RedisMessageReceiver {
}
private void setupReceivers() {
ChatMessageReceiver chatRx = new ChatMessageReceiver(bbbGW);
receivers.add(chatRx);
LockMessageReceiver lockRx = new LockMessageReceiver(bbbGW);
receivers.add(lockRx);
PresentationMessageListener presRx = new PresentationMessageListener(bbbGW);
receivers.add(presRx);
UsersMessageReceiver usersRx = new UsersMessageReceiver(bbbGW);
receivers.add(usersRx);
WhiteboardMessageReceiver whiteboardRx = new WhiteboardMessageReceiver(bbbGW);
receivers.add(whiteboardRx);
DeskShareMessageReceiver deskShareRx = new DeskShareMessageReceiver(bbbGW);
receivers.add(deskShareRx);
PollingMessageReceiver pollRx = new PollingMessageReceiver(bbbGW);
receivers.add(pollRx);
MeetingMessageReceiver meetingRx = new MeetingMessageReceiver(bbbGW);
receivers.add(meetingRx);
CaptionMessageReceiver captionRx = new CaptionMessageReceiver(bbbGW);
receivers.add(captionRx);
}
public void handleMessage(String pattern, String channel, String message) {

View File

@ -30,219 +30,15 @@ public class UsersMessageReceiver implements MessageHandler{
if (header.has("name")) {
String messageName = header.get("name").getAsString();
switch (messageName) {
case UserLeavingMessage.USER_LEAVING:
processUserLeavingMessage(message);
break;
case AllowUserToShareDesktopRequest.NAME:
processAllowUserToShareDesktopRequest(message);
break;
case AssignPresenterRequestMessage.ASSIGN_PRESENTER_REQUEST:
processAssignPresenterRequestMessage(message);
break;
case UserEmojiStatusMessage.USER_EMOJI_STATUS:
processUserEmojiStatusMessage(message);
break;
case EjectUserFromMeetingRequestMessage.EJECT_USER_FROM_MEETING_REQUEST:
processEjectUserFromMeetingRequestMessage(message);
break;
case UserShareWebcamRequestMessage.USER_SHARE_WEBCAM_REQUEST:
processUserShareWebcamRequestMessage(message);
break;
case UserUnshareWebcamRequestMessage.USER_UNSHARE_WEBCAM_REQUEST:
processUserUnshareWebcamRequestMessage(message);
break;
case SetUserStatusRequestMessage.SET_USER_STATUS_REQUEST:
processSetUserStatusRequestMessage(message);
break;
case SetRecordingStatusRequestMessage.SET_RECORDING_STATUS_REQUEST:
processSetRecordingStatusRequestMessage(message);
break;
case GetRecordingStatusRequestMessage.GET_RECORDING_STATUS_REQUEST:
processGetRecordingStatusRequestMessage(message);
break;
case GetUsersRequestMessage.GET_USERS_REQUEST:
processGetUsersRequestMessage(message);
break;
case InitPermissionsSettingMessage.INIT_PERMISSIONS_SETTING:
processInitPermissionsSettingMessage(message);
break;
case InitAudioSettingsMessage.INIT_AUDIO_SETTING:
processInitAudioSettingsMessage(message);
break;
case BroadcastLayoutRequestMessage.BROADCAST_LAYOUT_REQUEST:
processBroadcastLayoutRequestMessage(message);
break;
case LockLayoutRequestMessage.LOCK_LAYOUT_REQUEST:
processLockLayoutRequestMessage(message);
break;
case GetCurrentLayoutRequestMessage.GET_CURRENT_LAYOUT_REQUEST:
processGetCurrentLayoutRequestMessage(message);
break;
case MuteAllExceptPresenterRequestMessage.MUTE_ALL_EXCEPT_PRESENTER_REQUEST:
processMuteAllExceptPresenterRequestMessage(message);
break;
case MuteAllRequestMessage.MUTE_ALL_REQUEST:
processMuteAllRequestMessage(message);
break;
case IsMeetingMutedRequestMessage.IS_MEETING_MUTED_REQUEST:
processIsMeetingMutedRequestMessage(message);
break;
case MuteUserRequestMessage.MUTE_USER_REQUEST:
processMuteUserRequestMessage(message);
break;
case LockMuteUserRequestMessage.LOCK_MUTE_USER_REQUEST:
processLockMuteUserRequestMessage(message);
break;
case EjectUserFromVoiceRequestMessage.EJECT_USER_FROM_VOICE_REQUEST:
processEjectUserFromVoiceRequestMessage(message);
break;
case GetBreakoutRoomsList.NAME:
bbbInGW.handleJsonMessage(message);
break;
case CreateBreakoutRoomsRequest.NAME:
bbbInGW.handleJsonMessage(message);
break;
case ListenInOnBreakout.NAME:
bbbInGW.handleJsonMessage(message);
break;
case RequestBreakoutJoinURL.NAME:
bbbInGW.handleJsonMessage(message);
break;
case EndAllBreakoutRoomsRequest.NAME:
bbbInGW.handleJsonMessage(message);
break;
}
}
}
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_VOICE_CONF_SYSTEM_CHAN)) {
//System.out.println("Voice message: " + channel + " " + message);
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
switch (messageName) {
case UserJoinedVoiceConfMessage.USER_JOINED_VOICE_CONF:
processUserJoinedVoiceConfMessage(message);
break;
case UserLeftVoiceConfMessage.USER_LEFT_VOICE_CONF:
processUserLeftVoiceConfMessage(message);
break;
case UserLockedInVoiceConfMessage.USER_LOCKED_IN_VOICE_CONF:
processUserLockedInVoiceConfMessage(message);
break;
case UserMutedInVoiceConfMessage.USER_MUTED_IN_VOICE_CONF:
processUserMutedInVoiceConfMessage(message);
break;
case UserTalkingInVoiceConfMessage.USER_TALKING_IN_VOICE_CONF:
processUserTalkingInVoiceConfMessage(message);
break;
case VoiceConfRecordingStartedMessage.VOICE_CONF_RECORDING_STARTED:
processVoiceConfRecordingStartedMessage(message);
break;
}
}
}
}
}
private void processUserJoinedVoiceConfMessage(String json) {
UserJoinedVoiceConfMessage msg = UserJoinedVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserJoined(msg.voiceConfId, msg.voiceUserId, msg.userId, msg.callerIdName, msg.callerIdNum, msg.muted, msg.avatarURL, msg.talking);
}
}
private void processUserLeftVoiceConfMessage(String json) {
UserLeftVoiceConfMessage msg = UserLeftVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserLeft(msg.voiceConfId, msg.voiceUserId);
}
}
private void processUserLockedInVoiceConfMessage(String json) {
UserLockedInVoiceConfMessage msg = UserLockedInVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserLocked(msg.voiceConfId, msg.voiceUserId, msg.locked);
}
}
private void processUserMutedInVoiceConfMessage(String json) {
UserMutedInVoiceConfMessage msg = UserMutedInVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserMuted(msg.voiceConfId, msg.voiceUserId, msg.muted);
}
}
private void processUserTalkingInVoiceConfMessage(String json) {
UserTalkingInVoiceConfMessage msg = UserTalkingInVoiceConfMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceUserTalking(msg.voiceConfId, msg.voiceUserId, msg.talking);
}
}
private void processVoiceConfRecordingStartedMessage(String json) {
VoiceConfRecordingStartedMessage msg = VoiceConfRecordingStartedMessage.fromJson(json);
if (msg != null) {
bbbInGW.voiceRecording(msg.voiceConfId, msg.recordStream, msg.timestamp, msg.recording);
}
}
private void processUserLeavingMessage(String message) {
UserLeavingMessage ulm = UserLeavingMessage.fromJson(message);
if (ulm != null) {
bbbInGW.userLeft(ulm.meetingId, ulm.userId, ulm.meetingId);
}
}
private void processAllowUserToShareDesktopRequest(String message) {
AllowUserToShareDesktopRequest msg = AllowUserToShareDesktopRequest.fromJson(message);
if (msg != null) {
bbbInGW.checkIfAllowedToShareDesktop(msg.meetingId, msg.userId);
}
}
private void processAssignPresenterRequestMessage(String message) {
AssignPresenterRequestMessage apm = AssignPresenterRequestMessage.fromJson(message);
if (apm != null) {
bbbInGW.assignPresenter(apm.meetingId, apm.newPresenterId, apm.newPresenterName, apm.assignedBy);
}
}
private void processUserEmojiStatusMessage(String message) {
UserEmojiStatusMessage uesm = UserEmojiStatusMessage.fromJson(message);
if (uesm != null) {
bbbInGW.userEmojiStatus(uesm.meetingId, uesm.userId, uesm.emojiStatus);
}
}
private void processEjectUserFromMeetingRequestMessage(String message) {
EjectUserFromMeetingRequestMessage eufm = EjectUserFromMeetingRequestMessage.fromJson(message);
if (eufm != null) {
bbbInGW.ejectUserFromMeeting(eufm.meetingId, eufm.userId, eufm.ejectedBy);
}
}
private void processUserShareWebcamRequestMessage(String message) {
UserShareWebcamRequestMessage msg = UserShareWebcamRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.shareWebcam(msg.meetingId, msg.userId, msg.stream);
}
}
private void processUserUnshareWebcamRequestMessage(String message) {
UserUnshareWebcamRequestMessage msg = UserUnshareWebcamRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.unshareWebcam(msg.meetingId, msg.userId, msg.stream);
}
}
private void processSetUserStatusRequestMessage(String message) {
SetUserStatusRequestMessage msg = SetUserStatusRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.setUserStatus(msg.meetingId, msg.userId, msg.status, msg.value);
}
}
@ -259,88 +55,4 @@ public class UsersMessageReceiver implements MessageHandler{
bbbInGW.getRecordingStatus(msg.meetingId, msg.userId);
}
}
private void processGetUsersRequestMessage(String message) {
GetUsersRequestMessage msg = GetUsersRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.getUsers(msg.meetingId, msg.requesterId);
}
}
private void processInitPermissionsSettingMessage(String message) {
InitPermissionsSettingMessage msg = InitPermissionsSettingMessage.fromJson(message);
if (msg != null) {
bbbInGW.initLockSettings(msg.meetingId, msg.permissions);
}
}
private void processInitAudioSettingsMessage(String message) {
InitAudioSettingsMessage msg = InitAudioSettingsMessage.fromJson(message);
if (msg != null) {
bbbInGW.initAudioSettings(msg.meetingId, msg.userId, msg.muted);
}
}
private void processBroadcastLayoutRequestMessage(String message) {
BroadcastLayoutRequestMessage msg = BroadcastLayoutRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.broadcastLayout(msg.meetingId, msg.userId, msg.layout);
}
}
private void processLockLayoutRequestMessage(String message) {
LockLayoutRequestMessage msg = LockLayoutRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.lockLayout(msg.meetingId, msg.userId, msg.lock, msg.viewersOnly, msg.layout);
}
}
private void processGetCurrentLayoutRequestMessage(String message) {
GetCurrentLayoutRequestMessage msg = GetCurrentLayoutRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.getCurrentLayout(msg.meetingId, msg.userId);
}
}
private void processMuteAllExceptPresenterRequestMessage(String message) {
MuteAllExceptPresenterRequestMessage msg = MuteAllExceptPresenterRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.muteAllExceptPresenter(msg.meetingId, msg.requesterId, msg.mute);
}
}
private void processMuteAllRequestMessage(String message) {
MuteAllRequestMessage msg = MuteAllRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.muteAllUsers(msg.meetingId, msg.requesterId, msg.mute);
}
}
private void processIsMeetingMutedRequestMessage(String message) {
IsMeetingMutedRequestMessage msg = IsMeetingMutedRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.isMeetingMuted(msg.meetingId, msg.requesterId);
}
}
private void processMuteUserRequestMessage(String message) {
MuteUserRequestMessage msg = MuteUserRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.muteUser(msg.meetingId, msg.requesterId, msg.userId, msg.mute);
}
}
private void processLockMuteUserRequestMessage(String message) {
LockMuteUserRequestMessage msg = LockMuteUserRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.lockMuteUser(msg.meetingId, msg.requesterId, msg.userId, msg.lock);
}
}
private void processEjectUserFromVoiceRequestMessage(String message) {
EjectUserFromVoiceRequestMessage msg = EjectUserFromVoiceRequestMessage.fromJson(message);
if (msg != null) {
bbbInGW.ejectUserFromVoice(msg.meetingId, msg.userId, msg.requesterId);
}
}
}

View File

@ -1,60 +0,0 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.ClearWhiteboardRequestMessage;
import org.bigbluebutton.common.messages.EnableWhiteboardRequestMessage;
import org.bigbluebutton.common.messages.IsWhiteboardEnabledRequestMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.RequestWhiteboardAnnotationHistoryRequestMessage;
import org.bigbluebutton.common.messages.SendWhiteboardAnnotationRequestMessage;
import org.bigbluebutton.common.messages.UndoWhiteboardRequest;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
public class WhiteboardMessageReceiver implements MessageHandler {
private IBigBlueButtonInGW bbbInGW;
public WhiteboardMessageReceiver(IBigBlueButtonInGW bbbInGW) {
this.bbbInGW = bbbInGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_WHITEBOARD_CHANNEL)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (UndoWhiteboardRequest.UNDO_WHITEBOARD_REQUEST.equals(messageName)) {
UndoWhiteboardRequest msg = UndoWhiteboardRequest.fromJson(message);
bbbInGW.undoWhiteboard(msg.meetingId, msg.requesterId, msg.whiteboardId);
} else if (ClearWhiteboardRequestMessage.CLEAR_WHITEBOARD_REQUEST.equals(messageName)) {
ClearWhiteboardRequestMessage msg = ClearWhiteboardRequestMessage.fromJson(message);
bbbInGW.clearWhiteboard(msg.meetingId, msg.requesterId, msg.whiteboardId);
} else if (RequestWhiteboardAnnotationHistoryRequestMessage.REQUEST_WHITEBOARD_ANNOTATION_HISTORY_REQUEST.equals(messageName)) {
RequestWhiteboardAnnotationHistoryRequestMessage msg = RequestWhiteboardAnnotationHistoryRequestMessage.fromJson(message);
bbbInGW.requestWhiteboardAnnotationHistory(msg.meetingId, msg.requesterId, msg.whiteboardId, msg.replyTo);
} else if (IsWhiteboardEnabledRequestMessage.IS_WHITEBOARD_ENABLED_REQUEST.equals(messageName)) {
IsWhiteboardEnabledRequestMessage msg = IsWhiteboardEnabledRequestMessage.fromJson(message);
bbbInGW.isWhiteboardEnabled(msg.meetingId, msg.requesterId, msg.replyTo);
} else if (EnableWhiteboardRequestMessage.ENABLE_WHITEBOARD_REQUEST.equals(messageName)) {
EnableWhiteboardRequestMessage msg = EnableWhiteboardRequestMessage.fromJson(message);
bbbInGW.enableWhiteboard(msg.meetingId, msg.requesterId, msg.enable);
} else if (SendWhiteboardAnnotationRequestMessage.SEND_WHITEBOARD_ANNOTATION_REQUEST.equals(messageName)) {
SendWhiteboardAnnotationRequestMessage msg = SendWhiteboardAnnotationRequestMessage.fromJson(message);
bbbInGW.sendWhiteboardAnnotation(msg.meetingId, msg.requesterId, msg.annotation);
}
}
}
}
}
}

View File

@ -1,28 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import org.bigbluebutton.core.service.recorder.RecordEvent;
public abstract class AbstractCaptionRecordEvent extends RecordEvent {
public AbstractCaptionRecordEvent() {
setModule("CAPTION");
}
}

View File

@ -1,28 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import org.bigbluebutton.core.service.recorder.RecordEvent;
public abstract class AbstractChatRecordEvent extends RecordEvent {
public AbstractChatRecordEvent() {
setModule("CHAT");
}
}

View File

@ -1,28 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import org.bigbluebutton.core.service.recorder.RecordEvent;
public abstract class AbstractDeskShareRecordEvent extends RecordEvent {
public AbstractDeskShareRecordEvent() {
setModule("DESKSHARE");
}
}

View File

@ -1,28 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import org.bigbluebutton.core.service.recorder.RecordEvent;
public abstract class AbstractParticipantRecordEvent extends RecordEvent {
public AbstractParticipantRecordEvent() {
setModule("PARTICIPANT");
}
}

View File

@ -1,28 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import org.bigbluebutton.core.service.recorder.RecordEvent;
public abstract class AbstractPresentationRecordEvent extends RecordEvent {
public AbstractPresentationRecordEvent() {
setModule("PRESENTATION");
}
}

View File

@ -1,46 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import org.bigbluebutton.core.service.recorder.RecordEvent;
public abstract class AbstractWhiteboardRecordEvent extends RecordEvent {
public AbstractWhiteboardRecordEvent() {
setModule("WHITEBOARD");
}
public void setPresentation(String name) {
eventMap.put("presentation", name);
}
public void setPageNumber(String page) {
/**
* Subtract 1 from the page number to be zero-based to be
* compatible with 0.81 and earlier. (ralam Sept 2, 2014)
*/
Integer num = new Integer(page);
// System.out.println("WB Page Number real pagenum=[" + num + "] rec pagenum=[" + (num - 1) + "]");
eventMap.put("pageNumber", new Integer(num - 1).toString());
}
public void setWhiteboardId(String id) {
eventMap.put("whiteboardId", id);
}
}

View File

@ -1,69 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import java.util.ArrayList;
import java.util.Map;
public class AddShapeWhiteboardRecordEvent extends AbstractWhiteboardRecordEvent {
public AddShapeWhiteboardRecordEvent() {
super();
setEvent("AddShapeEvent");
}
public void addAnnotation(Map<String, Object> annotation) {
for (Map.Entry<String, Object> entry : annotation.entrySet()) {
String key = entry.getKey();
if (key.equals("points")) {
eventMap.put("dataPoints", pointsToString((ArrayList<Object>)entry.getValue()));
} else {
Object value = entry.getValue();
eventMap.put(key, value.toString());
}
}
}
private String pointsToString(ArrayList<Object> points){
String datapoints = "";
for (int i = 0; i < points.size(); i++) {
datapoints += (points.get(i)).toString() + ",";
}
// Trim the trailing comma
return datapoints.substring(0, datapoints.length() - 1);
}
public void setFillColor(int fillColor) {
eventMap.put("fillColor", Integer.toString(fillColor));
}
public void setThickness(int thickness) {
eventMap.put("thickness", Integer.toString(thickness));
}
public void setFill(boolean fill) {
eventMap.put("fill", Boolean.toString(fill));
}
public void setTransparent(boolean transparent) {
eventMap.put("transparent", Boolean.toString(transparent));
}
}

View File

@ -1,54 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import java.util.ArrayList;
import java.util.Map;
public class AddTextWhiteboardRecordEvent extends AbstractWhiteboardRecordEvent {
public AddTextWhiteboardRecordEvent() {
super();
setEvent("AddTextEvent");
}
public void addAnnotation(Map<String, Object> annotation) {
for (Map.Entry<String, Object> entry : annotation.entrySet()) {
String key = entry.getKey();
if (key.equals("points")) {
ArrayList<Double> value = (ArrayList<Double>)entry.getValue();
eventMap.put("dataPoints", pointsToString(value));
} else {
Object value = entry.getValue();
eventMap.put(key, value.toString());
}
}
}
private String pointsToString(ArrayList<Double> points){
String datapoints = "";
for (Double i : points) {
datapoints += i + ",";
}
// Trim the trailing comma
return datapoints.substring(0, datapoints.length() - 1);
}
}

View File

@ -1,39 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class AssignPresenterRecordEvent extends AbstractParticipantRecordEvent {
public AssignPresenterRecordEvent() {
super();
setEvent("AssignPresenterEvent");
}
public void setUserId(String userid) {
eventMap.put("userid", userid);
}
public void setName(String name) {
eventMap.put("name", name);
}
public void setAssignedBy(String by) {
eventMap.put("assignedBy", by);
}
}

View File

@ -1,28 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ClearPageWhiteboardRecordEvent extends
AbstractWhiteboardRecordEvent {
public ClearPageWhiteboardRecordEvent() {
super();
setEvent("ClearPageEvent");
}
}

View File

@ -1,40 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ConversionCompletedPresentationRecordEvent extends
AbstractPresentationRecordEvent {
public ConversionCompletedPresentationRecordEvent() {
super();
setEvent("ConversionCompletedEvent");
}
public void setPresentationName(String name) {
eventMap.put("presentationName", name);
}
public void setOriginalFilename(String name) {
eventMap.put("originalFilename", name);
}
public void setSlidesInfo(String slidesInfo) {
eventMap.put("slidesInfo", slidesInfo);
}
}

View File

@ -1,36 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class CursorUpdateRecordEvent extends AbstractPresentationRecordEvent{
public CursorUpdateRecordEvent() {
super();
setEvent("CursorMoveEvent");
}
public void setXPercent(double percent) {
eventMap.put("xOffset", Double.toString(percent));
}
public void setYPercent(double percent) {
eventMap.put("yOffset", Double.toString(percent));
}
}

View File

@ -1,26 +0,0 @@
package org.bigbluebutton.core.recorders.events;
public class DeskShareNotifyViewersRTMPRecordEvent extends
AbstractDeskShareRecordEvent {
public DeskShareNotifyViewersRTMPRecordEvent() {
super();
setEvent("DeskShareNotifyViewersRTMP");
}
public void setStreamPath(String streamPath) {
eventMap.put("streamPath", streamPath);
}
public void setBroadcasting(Boolean broadcasting) {
eventMap.put("broadcasting", broadcasting.toString());
}
public void setVideoWidth(int videoWidth) {
eventMap.put("videoWidth", Integer.toString(videoWidth));
}
public void setVideoHeight(int videoHeight) {
eventMap.put("videoHeight", Integer.toString(videoHeight));
}
}

View File

@ -1,14 +0,0 @@
package org.bigbluebutton.core.recorders.events;
public class DeskShareStartRTMPRecordEvent extends
AbstractDeskShareRecordEvent {
public DeskShareStartRTMPRecordEvent() {
super();
setEvent("DeskShareStartRTMP");
}
public void setStreamPath(String streamPath) {
eventMap.put("streamPath", streamPath);
}
}

View File

@ -1,14 +0,0 @@
package org.bigbluebutton.core.recorders.events;
public class DeskShareStopRTMPRecordEvent extends
AbstractDeskShareRecordEvent {
public DeskShareStopRTMPRecordEvent() {
super();
setEvent("DeskShareStopRTMP");
}
public void setStreamPath(String streamPath) {
eventMap.put("streamPath", streamPath);
}
}

View File

@ -1,53 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class EditCaptionHistoryRecordEvent extends AbstractCaptionRecordEvent {
private static final String START_INDEX = "startIndex";
private static final String END_INDEX = "endIndex";
private static final String LOCALE = "locale";
private static final String LOCALE_CODE = "localeCode";
private static final String TEXT = "text";
public EditCaptionHistoryRecordEvent() {
super();
setEvent("EditCaptionHistoryEvent");
}
public void setStartIndex(String startIndex) {
eventMap.put(START_INDEX, startIndex);
}
public void setEndIndex(String endIndex) {
eventMap.put(END_INDEX, endIndex);
}
public void setLocale(String locale) {
eventMap.put(LOCALE, locale);
}
public void setLocaleCode(String localeCode) {
eventMap.put(LOCALE_CODE, localeCode);
}
public void setText(String text) {
eventMap.put(TEXT, text);
}
}

View File

@ -1,40 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class GenerateSlidePresentationRecordEvent extends
AbstractPresentationRecordEvent {
public GenerateSlidePresentationRecordEvent() {
super();
setEvent("GenerateSlideEvent");
}
public void setPresentationName(String name) {
eventMap.put("presentationName", name);
}
public void setNumberOfPages(int numPages) {
eventMap.put("numberOfPages", Integer.toString(numPages));
}
public void setPagesCompleted(int pagesCompleted) {
eventMap.put("pagesCompleted", Integer.toString(pagesCompleted));
}
}

View File

@ -1,81 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class GotoSlidePresentationRecordEvent extends
AbstractPresentationRecordEvent {
public GotoSlidePresentationRecordEvent() {
super();
setEvent("GotoSlideEvent");
}
public void setSlide(int slide) {
/**
* Subtract 1 from the page number to be zero-based to be
* compatible with 0.81 and earlier. (ralam Sept 2, 2014)
*/
eventMap.put("slide", Integer.toString(slide - 1));
}
public void setId(String id) {
eventMap.put("id", id);
}
public void setNum(int num) {
eventMap.put("num", Integer.toString(num));
}
public void setCurrent(boolean current) {
eventMap.put("current", Boolean.toString(current));
}
public void setThumbUri(String thumbUri) {
eventMap.put("thumbUri", thumbUri);
}
public void setSwfUri(String swfUri) {
eventMap.put("swfUri", swfUri);
}
public void setTxtUri(String txtUri) {
eventMap.put("txtUri", txtUri);
}
public void setSvgUri(String svgUri) {
eventMap.put("svgUri", svgUri);
}
public void setXOffset(double offset) {
eventMap.put("xOffset", Double.toString(offset));
}
public void setYOffset(double offset) {
eventMap.put("yOffset", Double.toString(offset));
}
public void setWidthRatio(double ratio) {
eventMap.put("widthRatio", Double.toString(ratio));
}
public void setHeightRatio(double ratio) {
eventMap.put("heightRatio", Double.toString(ratio));
}
}

View File

@ -1,53 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
import java.util.ArrayList;
import java.util.Map;
public class ModifyTextWhiteboardRecordEvent extends AbstractWhiteboardRecordEvent {
public ModifyTextWhiteboardRecordEvent() {
super();
setEvent("ModifyTextEvent");
}
public void addAnnotation(Map<String, Object> annotation) {
for (Map.Entry<String, Object> entry : annotation.entrySet()) {
String key = entry.getKey();
if (key.equals("points")) {
ArrayList<Double> value = (ArrayList<Double>)entry.getValue();
eventMap.put("dataPoints", pointsToString(value));
} else {
Object value = entry.getValue();
eventMap.put(key, value.toString());
}
}
}
private String pointsToString(ArrayList<Double> points){
String datapoints = "";
for (Double i : points) {
datapoints += i + ",";
}
// Trim the trailing comma
return datapoints.substring(0, datapoints.length() - 1);
}
}

View File

@ -1,27 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantEndAndKickAllRecordEvent extends AbstractParticipantRecordEvent {
public ParticipantEndAndKickAllRecordEvent() {
super();
setEvent("EndAndKickAllEvent");
}
}

View File

@ -1,51 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantJoinRecordEvent extends AbstractParticipantRecordEvent {
public ParticipantJoinRecordEvent() {
super();
setEvent("ParticipantJoinEvent");
}
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
public void setExternalUserId(String externalUserId) {
eventMap.put("externalUserId", externalUserId);
}
public void setName(String name){
eventMap.put("name",name);
}
/**
* Sets the role of the user as MODERATOR or VIEWER
* @param role
*/
public void setRole(String role) {
eventMap.put("role", role);
}
public void setStatus(String status) {
eventMap.put("status", status);
}
}

View File

@ -1,51 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantJoinedVoiceRecordEvent extends AbstractVoiceRecordEvent {
public ParticipantJoinedVoiceRecordEvent() {
super();
setEvent("ParticipantJoinedEvent");
}
public void setParticipant(String p) {
eventMap.put("participant", p);
}
public void setCallerName(String name) {
eventMap.put("callername", name);
}
public void setCallerNumber(String name) {
eventMap.put("callernumber", name);
}
public void setMuted(boolean muted) {
eventMap.put("muted", Boolean.toString(muted));
}
public void setTalking(boolean talking) {
eventMap.put("talking", Boolean.toString(talking));
}
public void setLocked(boolean locked) {
eventMap.put("locked", Boolean.toString(locked));
}
}

View File

@ -1,32 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantLeftRecordEvent extends AbstractParticipantRecordEvent {
public ParticipantLeftRecordEvent() {
super();
setEvent("ParticipantLeftEvent");
}
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
}

View File

@ -1,31 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantLeftVoiceRecordEvent extends AbstractVoiceRecordEvent {
public ParticipantLeftVoiceRecordEvent() {
super();
setEvent("ParticipantLeftEvent");
}
public void setParticipant(String p) {
eventMap.put("participant", p);
}
}

View File

@ -1,35 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantLockedVoiceRecordEvent extends AbstractVoiceRecordEvent {
public ParticipantLockedVoiceRecordEvent() {
super();
setEvent("ParticipantLockedEvent");
}
public void setParticipant(String p) {
eventMap.put("participant", p);
}
public void setLocked(boolean locked) {
eventMap.put("locked", Boolean.toString(locked));
}
}

View File

@ -1,35 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantMutedVoiceRecordEvent extends AbstractVoiceRecordEvent {
public ParticipantMutedVoiceRecordEvent() {
super();
setEvent("ParticipantMutedEvent");
}
public void setParticipant(String p) {
eventMap.put("participant", p);
}
public void setMuted(boolean muted) {
eventMap.put("muted", Boolean.toString(muted));
}
}

View File

@ -1,39 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantStatusChangeRecordEvent extends AbstractParticipantRecordEvent {
public ParticipantStatusChangeRecordEvent() {
super();
setEvent("ParticipantStatusChangeEvent");
}
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
public void setStatus(String status) {
eventMap.put("status", status);
}
public void setValue(String value) {
eventMap.put("value", value);
}
}

View File

@ -1,36 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ParticipantTalkingVoiceRecordEvent extends AbstractVoiceRecordEvent {
public ParticipantTalkingVoiceRecordEvent() {
super();
setEvent("ParticipantTalkingEvent");
}
public void setParticipant(String p) {
eventMap.put("participant", p);
}
public void setTalking(boolean talking) {
eventMap.put("talking", Boolean.toString(talking));
}
}

View File

@ -1,48 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class PublicChatRecordEvent extends AbstractChatRecordEvent {
private static final String SENDER = "sender";
private static final String SENDERID = "senderId";
private static final String MESSAGE = "message";
private static final String COLOR = "color";
public PublicChatRecordEvent() {
super();
setEvent("PublicChatEvent");
}
public void setSender(String sender) {
eventMap.put(SENDER, sender);
}
public void setSenderId(String senderId) {
eventMap.put(SENDERID, senderId);
}
public void setMessage(String message) {
eventMap.put(MESSAGE, message);
}
public void setColor(String color) {
eventMap.put(COLOR, color);
}
}

View File

@ -1,35 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class RecordStatusRecordEvent extends AbstractParticipantRecordEvent {
public RecordStatusRecordEvent() {
super();
setEvent("RecordStatusEvent");
}
public void setUserId(String userId) {
eventMap.put("userId", userId);
}
public void setRecordingStatus(String status) {
eventMap.put("status", status);
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class RemovePresentationPresentationRecordEvent extends
AbstractPresentationRecordEvent {
public RemovePresentationPresentationRecordEvent() {
super();
setEvent("RemovePresentationEvent");
}
public void setPresentationName(String name) {
eventMap.put("presentationName", name);
}
}

View File

@ -1,72 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ResizeAndMoveSlidePresentationRecordEvent extends
AbstractPresentationRecordEvent {
public ResizeAndMoveSlidePresentationRecordEvent() {
super();
setEvent("ResizeAndMoveSlideEvent");
}
public void setId(String id) {
eventMap.put("id", id);
}
public void setNum(int num) {
eventMap.put("num", Integer.toString(num));
}
public void setCurrent(boolean current) {
eventMap.put("current", Boolean.toString(current));
}
public void setThumbUri(String thumbUri) {
eventMap.put("thumbUri", thumbUri);
}
public void setSwfUri(String swfUri) {
eventMap.put("swfUri", swfUri);
}
public void setTxtUri(String txtUri) {
eventMap.put("txtUri", txtUri);
}
public void setSvgUri(String svgUri) {
eventMap.put("svgUri", svgUri);
}
public void setXOffset(double offset) {
eventMap.put("xOffset", Double.toString(offset));
}
public void setYOffset(double offset) {
eventMap.put("yOffset", Double.toString(offset));
}
public void setWidthRatio(double ratio) {
eventMap.put("widthRatio", Double.toString(ratio));
}
public void setHeightRatio(double ratio) {
eventMap.put("heightRatio", Double.toString(ratio));
}
}

View File

@ -1,40 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class SharePresentationPresentationRecordEvent extends
AbstractPresentationRecordEvent {
public SharePresentationPresentationRecordEvent() {
super();
setEvent("SharePresentationEvent");
}
public void setPresentationName(String name) {
eventMap.put("presentationName", name);
}
public void setOriginalFilename(String name) {
eventMap.put("originalFilename", name);
}
public void setShare(boolean share) {
eventMap.put("share", Boolean.toString(share));
}
}

View File

@ -1,38 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class StartRecordingVoiceRecordEvent extends AbstractVoiceRecordEvent {
public StartRecordingVoiceRecordEvent(boolean record) {
super();
if (record)
setEvent("StartRecordingEvent");
else
setEvent("StopRecordingEvent");
}
public void setRecordingTimestamp(String timestamp) {
eventMap.put("recordingTimestamp", timestamp);
}
public void setFilename(String filename) {
eventMap.put("filename", filename);
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class ToggleGridWhiteboardRecordEvent extends
AbstractWhiteboardRecordEvent {
public ToggleGridWhiteboardRecordEvent() {
super();
setEvent("ToggleGridEvent");
}
public void setGridEnabled(boolean enabled) {
eventMap.put("gridEnabled", Boolean.toString(enabled));
}
}

View File

@ -1,32 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class UndoShapeWhiteboardRecordEvent extends
AbstractWhiteboardRecordEvent {
public UndoShapeWhiteboardRecordEvent() {
super();
setEvent("UndoShapeEvent");
}
public void setShapeId(String id) {
eventMap.put("shapeId", id);
}
}

View File

@ -1,32 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public abstract class VoiceConferenceRecordEvent {
private final String room;
public VoiceConferenceRecordEvent(String room) {
this.room = room;
}
public String getRoom() {
return room;
}
}

View File

@ -1,51 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class VoiceStartRecordingRecordEvent extends VoiceConferenceRecordEvent {
private String timestamp;
private String filename;
private boolean record;
public VoiceStartRecordingRecordEvent(String room, boolean record) {
super(room);
this.record = record;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public void setRecordingFilename(String filename) {
this.filename = filename;
}
public String getTimestamp() {
return timestamp;
}
public String getRecordingFilename() {
return filename;
}
public boolean startRecord() {
return record;
}
}

View File

@ -1,70 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class VoiceUserJoinedRecordEvent extends VoiceConferenceRecordEvent {
private final String voiceUserId;
private final String callerIdNum;
private final String callerIdName;
private final Boolean muted;
private final Boolean speaking;
private final Boolean locked = false;
private final String userId;
public VoiceUserJoinedRecordEvent(String userId, String voiceUserId, String room,
String callerIdNum, String callerIdName,
Boolean muted, Boolean speaking) {
super(room);
this.userId = userId;
this.voiceUserId = voiceUserId;
this.callerIdName = callerIdName;
this.callerIdNum = callerIdNum;
this.muted = muted;
this.speaking = speaking;
}
public String getUserId() {
return userId;
}
public String getVoiceUserId() {
return voiceUserId;
}
public String getCallerIdNum() {
return callerIdNum;
}
public String getCallerIdName() {
return callerIdName;
}
public Boolean getMuted() {
return muted;
}
public Boolean getSpeaking() {
return speaking;
}
public Boolean isLocked() {
return locked;
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class VoiceUserLeftRecordEvent extends VoiceConferenceRecordEvent {
private final String userId;
public VoiceUserLeftRecordEvent(String userId, String room) {
super(room);
this.userId = userId;
}
public String getUserId() {
return userId;
}
}

View File

@ -1,40 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class VoiceUserMutedRecordEvent extends VoiceConferenceRecordEvent {
private final boolean muted;
private final String userId;
public VoiceUserMutedRecordEvent(String userId, String room, boolean muted) {
super(room);
this.muted = muted;
this.userId = userId;
}
public String getUserId() {
return userId;
}
public boolean isMuted() {
return muted;
}
}

View File

@ -1,40 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.recorders.events;
public class VoiceUserTalkingRecordEvent extends VoiceConferenceRecordEvent {
private final boolean talking;
private final String userId;
public VoiceUserTalkingRecordEvent(String userId, String room, boolean talking) {
super(room);
this.talking = talking;
this.userId = userId;
}
public String getUserId() {
return userId;
}
public boolean isTalking() {
return talking;
}
}

View File

@ -1,85 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.service.recorder;
import java.util.HashMap;
/**
* Abstract class for all events that need to be recorded.
* @author Richard Alam
*
*/
public abstract class RecordEvent {
protected final HashMap<String, String> eventMap = new HashMap<String, String>();
protected final static String MODULE = "module";
protected final static String TIMESTAMP = "timestamp";
protected final static String MEETING = "meetingId";
protected final static String EVENT = "eventName";
public final String getMeetingID() {
return eventMap.get(MEETING);
}
/**
* Set the module that generated the event.
* @param module
*/
public final void setModule(String module) {
eventMap.put(MODULE, module);
}
/**
* Set the timestamp of the event.
* @param timestamp
*/
public final void setTimestamp(long timestamp) {
eventMap.put(TIMESTAMP, Long.toString(timestamp));
}
/**
* Set the meetingId for this particular event.
* @param meetingId
*/
public final void setMeetingId(String meetingId) {
eventMap.put(MEETING, meetingId);
}
/**
* Set the name of the event.
* @param event
*/
public final void setEvent(String event) {
eventMap.put(EVENT, event);
}
/**
* Convert the event into a Map to be recorded.
* @return
*/
public final HashMap<String, String> toMap() {
return eventMap;
}
@Override
public String toString() {
return eventMap.get(MODULE) + " " + eventMap.get(EVENT);
}
}

View File

@ -1,35 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.service.recorder;
/**
*
* The IRecorder interface define all the neccesary methods to implement for
* dispatch events to a JMS queue
*
* */
public interface Recorder {
/**
* Receive the messages from the bigbluebutton modules and send
* 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);
}

View File

@ -1,94 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.service.recorder;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
*
* The RecorderApplication class is used for setting the record module
* in BigBlueButton for send events messages to a JMS queue.
* The class follows the same standard as the others modules of BigBlueButton Apps.
*/
public class RecorderApplication {
private static final int NTHREADS = 1;
private static final Executor exec = Executors.newFixedThreadPool(NTHREADS);
private static final Executor runExec = Executors.newFixedThreadPool(NTHREADS);
private final BlockingQueue<RecordEvent> messages;
private volatile boolean recordEvents = false;
private final Recorder recorder;
public RecorderApplication(Recorder recorder) {
this.recorder = recorder;
messages = new LinkedBlockingQueue<RecordEvent>();
}
public void start() {
recordEvents = true;
Runnable sender = new Runnable() {
public void run() {
while (recordEvents) {
RecordEvent message;
try {
message = messages.take();
recordEvent(message);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
exec.execute(sender);
}
public void stop() {
recordEvents = false;
}
public void destroyRecordSession(String meetingID) {
// recordingSessions.remove(meetingID);
}
public void createRecordSession(String meetingID) {
// recordingSessions.put(meetingID, meetingID);
}
public void record(String meetingID, RecordEvent message) {
messages.offer(message);
}
private void recordEvent(final RecordEvent message) {
Runnable task = new Runnable() {
public void run() {
recorder.record(message.getMeetingID(), message);
}
};
runExec.execute(task);
}
}

View File

@ -1,69 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.service.recorder;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Protocol;
public class RedisDispatcher implements Recorder {
private static final String COLON=":";
private JedisPool redisPool;
private int keysExpiresInSec;
public RedisDispatcher(String host, int port, String password, int keysExpiresInSec) {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(32);
config.setMaxIdle(8);
config.setMinIdle(1);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
config.setTestWhileIdle(true);
config.setNumTestsPerEvictionRun(12);
config.setMaxWaitMillis(5000);
config.setTimeBetweenEvictionRunsMillis(60000);
config.setBlockWhenExhausted(true);
this.keysExpiresInSec = keysExpiresInSec;
// Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli
redisPool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, null,
Protocol.DEFAULT_DATABASE, "BbbAppsAkkaRec");
}
@Override
public void record(String session, RecordEvent message) {
Jedis jedis = redisPool.getResource();
try {
Long msgid = jedis.incr("global:nextRecordedMsgId");
String key = "recording" + COLON + session + COLON + msgid;
jedis.hmset(key, message.toMap());
jedis.expire(key, keysExpiresInSec);
key = "meeting" + COLON + session + COLON + "recordings";
jedis.rpush(key, msgid.toString());
jedis.expire(key, keysExpiresInSec);
} finally {
jedis.close();
}
}
}

View File

@ -1,5 +0,0 @@
package org.bigbluebutton.service.recording;
public class RecordMessage {
}

View File

@ -1,76 +0,0 @@
package org.bigbluebutton.service.recording;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import org.bigbluebutton.core.service.recorder.RecordEvent;
import com.google.gson.Gson;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class RedisListRecorder {
private static final int NTHREADS = 1;
private static final Executor exec = Executors.newFixedThreadPool(NTHREADS);
private static final Executor runExec = Executors.newFixedThreadPool(NTHREADS);
private BlockingQueue<RecordEvent> messages = new LinkedBlockingQueue<RecordEvent>();
private volatile boolean recordEvents = false;
JedisPool redisPool;
public void start() {
recordEvents = true;
Runnable sender = new Runnable() {
public void run() {
while (recordEvents) {
RecordEvent message;
try {
message = messages.take();
recordEvent(message);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
exec.execute(sender);
}
public void stop() {
recordEvents = false;
}
private void recordEvent(final RecordEvent message) {
Runnable task = new Runnable() {
public void run() {
Jedis jedis = redisPool.getResource();
try {
String key = "bbb:recording:" + message.getMeetingID();
Gson gson= new Gson();
jedis.rpush(key, gson.toJson(message.toMap()));
} finally {
redisPool.returnResource(jedis);
}
}
};
runExec.execute(task);
}
public void record(RecordEvent message) {
messages.offer(message);
}
public JedisPool getRedisPool() {
return redisPool;
}
public void setRedisPool(JedisPool redisPool) {
this.redisPool = redisPool;
}
}

View File

@ -35,9 +35,17 @@ redis {
keyExpiry=1209600
}
http {
interface = "0.0.0.0"
port = 9000
inactivity {
# time in seconds
deadline=7200
# inactivity warning message
timeLeft=300
}
expire {
# time in seconds
lastUserLeft = 60
neverJoined = 300
}
services {
@ -46,6 +54,28 @@ services {
}
red5 {
deskshareip="192.168.0.109"
deskshareip="10.130.218.89"
deskshareapp="video-broadcast"
}
eventBus {
meetingManagerChannel = "MeetingManagerChannel"
outMessageChannel = "OutgoingMessageChannel"
incomingJsonMsgChannel = "IncomingJsonMsgChannel"
outBbbMsgMsgChannel = "OutBbbMsgChannel"
}
sharedNotes {
maxNumberOfNotes = 3
maxNumberOfUndos = 30
}
http {
interface = "0.0.0.0"
port = 9999
}
services {
telizeHost = "www.telize.com"
telizePort = 80
}

View File

@ -1,58 +1,54 @@
package org.bigbluebutton
import akka.event.{ LoggingAdapter, Logging }
import akka.actor.{ ActorSystem, Props }
import scala.concurrent.duration._
import redis.RedisClient
import scala.concurrent.{ Future, Await }
import org.bigbluebutton.endpoint.redis.RedisPublisher
import org.bigbluebutton.endpoint.redis.KeepAliveRedisPublisher
import org.bigbluebutton.endpoint.redis.AppsRedisSubscriberActor
import org.bigbluebutton.core.api.MessageOutGateway
import org.bigbluebutton.core.api.IBigBlueButtonInGW
import org.bigbluebutton.core.BigBlueButtonInGW
import org.bigbluebutton.core.MessageSender
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.MessageSenderActor
import org.bigbluebutton.core.RecorderActor
import akka.event.Logging
import akka.actor.ActorSystem
import org.bigbluebutton.endpoint.redis.{ AppsRedisSubscriberActor, KeepAliveRedisPublisher, RedisPublisher, RedisRecorderActor }
import org.bigbluebutton.core._
import org.bigbluebutton.core.pubsub.receivers.RedisMessageReceiver
import org.bigbluebutton.core.api.OutMessageListener2
import org.bigbluebutton.core.pubsub.senders._
import org.bigbluebutton.core.service.recorder.RedisDispatcher
import org.bigbluebutton.core.service.recorder.RecorderApplication
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.JsonMessageSenderActor
import org.bigbluebutton.core.pubsub.senders.ReceivedJsonMsgHandlerActor
import org.bigbluebutton.core2.{ AnalyticsActor, FromAkkaAppsMsgSenderActor }
object Boot extends App with SystemConfiguration {
implicit val system = ActorSystem("bigbluebutton-apps-system")
implicit val executor = system.dispatcher
val logger = Logging(system, getClass)
val eventBus = new IncomingEventBus
val outgoingEventBus = new OutgoingEventBus
val eventBus = new InMsgBusGW(new IncomingEventBusImp())
val outGW = new OutMessageGateway(outgoingEventBus)
val outBus2 = new OutEventBus2
val recordingEventBus = new RecordingEventBus
val outGW = new OutMessageGatewayImp(outBus2)
val redisPublisher = new RedisPublisher(system)
val msgSender = new MessageSender(redisPublisher)
val redisDispatcher = new RedisDispatcher(redisHost, redisPort, redisPassword, keysExpiresInSec)
val recorderApp = new RecorderApplication(redisDispatcher)
recorderApp.start()
val redisRecorderActor = system.actorOf(RedisRecorderActor.props(system), "redisRecorderActor")
val messageSenderActor = system.actorOf(MessageSenderActor.props(msgSender), "messageSenderActor")
val recorderActor = system.actorOf(RecorderActor.props(recorderApp), "recorderActor")
val newMessageSenderActor = system.actorOf(JsonMessageSenderActor.props(msgSender), "newMessageSenderActor")
recordingEventBus.subscribe(redisRecorderActor, outMessageChannel)
val incomingJsonMessageBus = new IncomingJsonMessageBus
outgoingEventBus.subscribe(messageSenderActor, "outgoingMessageChannel")
outgoingEventBus.subscribe(recorderActor, "outgoingMessageChannel")
outgoingEventBus.subscribe(newMessageSenderActor, "outgoingMessageChannel")
val bbbMsgBus = new BbbMsgRouterEventBus
val bbbInGW = new BigBlueButtonInGW(system, eventBus, outGW, red5DeskShareIP, red5DeskShareApp)
val fromAkkaAppsMsgSenderActorRef = system.actorOf(FromAkkaAppsMsgSenderActor.props(msgSender))
val analyticsActorRef = system.actorOf(AnalyticsActor.props())
outBus2.subscribe(fromAkkaAppsMsgSenderActorRef, outBbbMsgMsgChannel)
outBus2.subscribe(redisRecorderActor, recordServiceMessageChannel)
outBus2.subscribe(analyticsActorRef, outBbbMsgMsgChannel)
bbbMsgBus.subscribe(analyticsActorRef, analyticsChannel)
val bbbInGW = new BigBlueButtonInGW(system, eventBus, bbbMsgBus, outGW)
val redisMsgReceiver = new RedisMessageReceiver(bbbInGW)
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(redisMsgReceiver), "redis-subscriber")
val redisMessageHandlerActor = system.actorOf(ReceivedJsonMsgHandlerActor.props(bbbMsgBus, incomingJsonMessageBus))
incomingJsonMessageBus.subscribe(redisMessageHandlerActor, toAkkaAppsJsonChannel)
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(redisMsgReceiver, incomingJsonMessageBus), "redis-subscriber")
val keepAliveRedisPublisher = new KeepAliveRedisPublisher(system, redisPublisher)
}

View File

@ -10,8 +10,7 @@ trait SystemConfiguration {
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)
lazy val redisPassword = Try(config.getString("redis.password")).getOrElse("")
lazy val httpInterface = Try(config.getString("http.interface")).getOrElse("")
lazy val httpPort = Try(config.getInt("http.port")).getOrElse(9090)
lazy val bbbWebHost = Try(config.getString("services.bbbWebHost")).getOrElse("localhost")
lazy val bbbWebPort = Try(config.getInt("services.bbbWebPort")).getOrElse(8888)
lazy val bbbWebAPI = Try(config.getString("services.bbbWebAPI")).getOrElse("localhost")
@ -21,4 +20,43 @@ trait SystemConfiguration {
lazy val keysExpiresInSec = Try(config.getInt("redis.keyExpiry")).getOrElse(14 * 86400) // 14 days
lazy val red5DeskShareIP = Try(config.getString("red5.deskshareip")).getOrElse("127.0.0.1")
lazy val red5DeskShareApp = Try(config.getString("red5.deskshareapp")).getOrElse("")
lazy val inactivityDeadline = Try(config.getInt("inactivity.deadline")).getOrElse(2 * 3600) // 2 hours
lazy val inactivityTimeLeft = Try(config.getInt("inactivity.timeLeft")).getOrElse(5 * 60) // 5 minutes
lazy val expireLastUserLeft = Try(config.getInt("expire.lastUserLeft")).getOrElse(60) // 1 minute
lazy val expireNeverJoined = Try(config.getInt("expire.neverJoined")).getOrElse(5 * 60) // 5 minutes
lazy val analyticsChannel = Try(config.getString("eventBus.analyticsChannel")).getOrElse("analytics-channel")
lazy val meetingManagerChannel = Try(config.getString("eventBus.meetingManagerChannel")).getOrElse("MeetingManagerChannel")
lazy val outMessageChannel = Try(config.getString("eventBus.outMessageChannel")).getOrElse("OutgoingMessageChannel")
lazy val incomingJsonMsgChannel = Try(config.getString("eventBus.incomingJsonMsgChannel")).getOrElse("IncomingJsonMsgChannel")
lazy val outBbbMsgMsgChannel = Try(config.getString("eventBus.outBbbMsgMsgChannel")).getOrElse("OutBbbMsgChannel")
lazy val recordServiceMessageChannel = Try(config.getString("eventBus.recordServiceMessageChannel")).getOrElse("RecordServiceMessageChannel")
lazy val toAkkaAppsRedisChannel = Try(config.getString("redis.toAkkaAppsRedisChannel")).getOrElse("to-akka-apps-redis-channel")
lazy val fromAkkaAppsRedisChannel = Try(config.getString("redis.fromAkkaAppsRedisChannel")).getOrElse("from-akka-apps-redis-channel")
lazy val toHTML5RedisChannel = Try(config.getString("redis.toHTML5RedisChannel")).getOrElse("to-html5-redis-channel")
lazy val fromAkkaAppsChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-channel")
lazy val toAkkaAppsChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-channel")
lazy val fromClientChannel = Try(config.getString("eventBus.fromClientChannel")).getOrElse("from-client-channel")
lazy val toClientChannel = Try(config.getString("eventBus.toClientChannel")).getOrElse("to-client-channel")
lazy val toAkkaAppsJsonChannel = Try(config.getString("eventBus.toAkkaAppsChannel")).getOrElse("to-akka-apps-json-channel")
lazy val fromAkkaAppsJsonChannel = Try(config.getString("eventBus.fromAkkaAppsChannel")).getOrElse("from-akka-apps-json-channel")
lazy val fromAkkaAppsOldJsonChannel = Try(config.getString("eventBus.fromAkkaAppsOldChannel")).getOrElse("from-akka-apps-old-json-channel")
lazy val toVoiceConfRedisChannel = Try(config.getString("redis.toVoiceConfRedisChannel")).getOrElse("to-voice-conf-redis-channel")
lazy val fromVoiceConfRedisChannel = Try(config.getString("redis.fromVoiceConfRedisChannel")).getOrElse("from-voice-conf-redis-channel")
lazy val fromAkkaAppsWbRedisChannel = Try(config.getString("redis.fromAkkaAppsWbRedisChannel")).getOrElse("from-akka-apps-wb-redis-channel")
lazy val fromAkkaAppsChatRedisChannel = Try(config.getString("redis.fromAkkaAppsChatRedisChannel")).getOrElse("from-akka-apps-chat-redis-channel")
lazy val fromAkkaAppsPresRedisChannel = Try(config.getString("redis.fromAkkaAppsPresRedisChannel")).getOrElse("from-akka-apps-pres-redis-channel")
lazy val maxNumberOfNotes = Try(config.getInt("sharedNotes.maxNumberOfNotes")).getOrElse(3)
lazy val maxNumberOfUndos = Try(config.getInt("sharedNotes.maxNumberOfUndos")).getOrElse(30)
lazy val httpInterface = Try(config.getString("http.interface")).getOrElse("")
lazy val httpPort = Try(config.getInt("http.port")).getOrElse(9090)
lazy val telizeHost = Try(config.getString("services.telizeHost")).getOrElse("")
lazy val telizePort = Try(config.getInt("services.telizePort")).getOrElse(80)
}

View File

@ -1,217 +1,169 @@
package org.bigbluebutton.core
import java.io.{ PrintWriter, StringWriter }
import akka.actor._
import akka.actor.ActorLogging
import akka.pattern.{ ask, pipe }
import akka.actor.SupervisorStrategy.Resume
import akka.util.Timeout
import scala.concurrent.duration._
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api._
import org.bigbluebutton.SystemConfiguration
import java.util.concurrent.TimeUnit
import org.bigbluebutton.common2.msgs._
import org.bigbluebutton.core.running.RunningMeeting
import org.bigbluebutton.core2.RunningMeetings
import org.bigbluebutton.core2.message.senders.MsgBuilder
object BigBlueButtonActor extends SystemConfiguration {
def props(system: ActorSystem,
eventBus: IncomingEventBus,
outGW: OutMessageGateway): Props =
Props(classOf[BigBlueButtonActor], system, eventBus, outGW)
def props(
system: ActorSystem,
eventBus: InternalEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway
): Props =
Props(classOf[BigBlueButtonActor], system, eventBus, bbbMsgBus, outGW)
}
class BigBlueButtonActor(val system: ActorSystem,
eventBus: IncomingEventBus, outGW: OutMessageGateway) extends Actor with ActorLogging {
class BigBlueButtonActor(
val system: ActorSystem,
val eventBus: InternalEventBus, val bbbMsgBus: BbbMsgRouterEventBus,
val outGW: OutMessageGateway
) extends Actor
with ActorLogging with SystemConfiguration {
implicit def executionContext = system.dispatcher
implicit val timeout = Timeout(5 seconds)
private var meetings = new collection.immutable.HashMap[String, RunningMeeting]
private val meetings = new RunningMeetings
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => {
val sw: StringWriter = new StringWriter()
sw.write("An exception has been thrown on BigBlueButtonActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n")
e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString())
Resume
}
}
override def preStart() {
bbbMsgBus.subscribe(self, meetingManagerChannel)
}
override def postStop() {
bbbMsgBus.unsubscribe(self, meetingManagerChannel)
}
def receive = {
case msg: CreateMeeting => handleCreateMeeting(msg)
case msg: DestroyMeeting => handleDestroyMeeting(msg)
case msg: KeepAliveMessage => handleKeepAliveMessage(msg)
case msg: PubSubPing => handlePubSubPingMessage(msg)
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg)
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg)
case msg: UserLockedInVoiceConfMessage => handleUserLockedInVoiceConfMessage(msg)
case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg)
case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg)
case msg: VoiceConfRecordingStartedMessage => handleVoiceConfRecordingStartedMessage(msg)
case _ => // do nothing
// Internal messages
case msg: DestroyMeetingInternalMsg => handleDestroyMeeting(msg)
// 2x messages
case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg)
case _ => // do nothing
}
private def findMeetingWithVoiceConfId(voiceConfId: String): Option[RunningMeeting] = {
meetings.values.find(m => { m.mProps.voiceBridge == voiceConfId })
}
private def handleUserJoinedVoiceConfMessage(msg: UserJoinedVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m => m.actorRef ! msg }
}
private def handleUserLeftVoiceConfMessage(msg: UserLeftVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
msg.core match {
case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
case m: CheckAlivePingSysMsg => handleCheckAlivePingSysMsg(m)
case _ => log.warning("Cannot handle " + msg.envelope.name)
}
}
private def handleUserLockedInVoiceConfMessage(msg: UserLockedInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
def handleRegisterUserReqMsg(msg: RegisterUserReqMsg): Unit = {
log.debug("RECEIVED RegisterUserReqMsg msg {}", msg)
for {
m <- RunningMeetings.findWithId(meetings, msg.header.meetingId)
} yield {
log.debug("FORWARDING Register user message")
m.actorRef forward (msg)
}
}
private def handleUserMutedInVoiceConfMessage(msg: UserMutedInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
def handleCreateMeetingReqMsg(msg: CreateMeetingReqMsg): Unit = {
log.debug("****** RECEIVED CreateMeetingReqMsg msg {}", msg)
private def handleVoiceConfRecordingStartedMessage(msg: VoiceConfRecordingStartedMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
RunningMeetings.findWithId(meetings, msg.body.props.meetingProp.intId) match {
case None =>
log.info("Create meeting request. meetingId={}", msg.body.props.meetingProp.intId)
}
private def handleUserTalkingInVoiceConfMessage(msg: UserTalkingInVoiceConfMessage) {
findMeetingWithVoiceConfId(msg.voiceConfId) foreach { m =>
m.actorRef ! msg
}
}
private def handleValidateAuthToken(msg: ValidateAuthToken) {
meetings.get(msg.meetingID) foreach { m =>
m.actorRef ! msg
// val future = m.actorRef.ask(msg)(5 seconds)
// future onComplete {
// case Success(result) => {
// log.info("Validate auth token response. meetingId=" + msg.meetingID + " userId=" + msg.userId + " token=" + msg.token)
// /**
// * Received a reply from MeetingActor which means hasn't hung!
// * Sometimes, the actor seems to hang and doesn't anymore accept messages. This is a simple
// * audit to check whether the actor is still alive. (ralam feb 25, 2015)
// */
// }
// case Failure(failure) => {
// log.warning("Validate auth token timeout. meetingId=" + msg.meetingID + " userId=" + msg.userId + " token=" + msg.token)
// outGW.send(new ValidateAuthTokenTimedOut(msg.meetingID, msg.userId, msg.token, false, msg.correlationId))
// }
// }
}
}
private def handleKeepAliveMessage(msg: KeepAliveMessage): Unit = {
outGW.send(new KeepAliveMessageReply(msg.aliveID))
}
private def handlePubSubPingMessage(msg: PubSubPing): Unit = {
outGW.send(new PubSubPong(msg.system, msg.timestamp))
}
private def handleDestroyMeeting(msg: DestroyMeeting) {
log.info("Received DestroyMeeting message for meetingId={}", msg.meetingID)
meetings.get(msg.meetingID) match {
case None => log.info("Could not find meetingId={}", msg.meetingID)
case Some(m) => {
meetings -= msg.meetingID
log.info("Kick everyone out on meetingId={}", msg.meetingID)
if (m.mProps.isBreakout) {
log.info("Informing parent meeting {} that a breakout room has been ended {}", m.mProps.parentMeetingID, m.mProps.meetingID)
eventBus.publish(BigBlueButtonEvent(m.mProps.parentMeetingID,
BreakoutRoomEnded(m.mProps.parentMeetingID, m.mProps.meetingID)))
}
// Eject all users using the client.
outGW.send(new EndAndKickAll(msg.meetingID, m.mProps.recorded))
// Eject all users from the voice conference
outGW.send(new EjectAllVoiceUsers(msg.meetingID, m.mProps.recorded, m.mProps.voiceBridge))
// Delay sending DisconnectAllUsers because of RTMPT connection being dropped before UserEject message arrives to the client
context.system.scheduler.scheduleOnce(Duration.create(2500, TimeUnit.MILLISECONDS)) {
// Disconnect all clients
outGW.send(new DisconnectAllUsers(msg.meetingID))
log.info("Destroyed meetingId={}", msg.meetingID)
outGW.send(new MeetingDestroyed(msg.meetingID))
/** Unsubscribe to meeting and voice events. **/
eventBus.unsubscribe(m.actorRef, m.mProps.meetingID)
eventBus.unsubscribe(m.actorRef, m.mProps.voiceBridge)
// Stop the meeting actor.
context.stop(m.actorRef)
}
}
}
}
private def handleCreateMeeting(msg: CreateMeeting): Unit = {
meetings.get(msg.meetingID) match {
case None => {
log.info("Create meeting request. meetingId={}", msg.mProps.meetingID)
var m = RunningMeeting(msg.mProps, outGW, eventBus)
val m = RunningMeeting(msg.body.props, outGW, eventBus)
/** Subscribe to meeting and voice events. **/
eventBus.subscribe(m.actorRef, m.mProps.meetingID)
eventBus.subscribe(m.actorRef, m.mProps.voiceBridge)
eventBus.subscribe(m.actorRef, m.mProps.deskshareBridge)
eventBus.subscribe(m.actorRef, m.props.meetingProp.intId)
eventBus.subscribe(m.actorRef, m.props.voiceProp.voiceConf)
eventBus.subscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
meetings += m.mProps.meetingID -> m
outGW.send(new MeetingCreated(m.mProps.meetingID, m.mProps.externalMeetingID, m.mProps.parentMeetingID,
m.mProps.recorded, m.mProps.meetingName, m.mProps.voiceBridge, msg.mProps.duration, msg.mProps.moderatorPass,
msg.mProps.viewerPass, msg.mProps.createTime, msg.mProps.createDate, msg.mProps.isBreakout))
bbbMsgBus.subscribe(m.actorRef, m.props.meetingProp.intId)
bbbMsgBus.subscribe(m.actorRef, m.props.voiceProp.voiceConf)
bbbMsgBus.subscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
RunningMeetings.add(meetings, m)
// Send new 2x message
val msgEvent = MsgBuilder.buildMeetingCreatedEvtMsg(m.props.meetingProp.intId, msg.body.props)
m.outMsgRouter.send(msgEvent)
case Some(m) =>
log.info("Meeting already created. meetingID={}", msg.body.props.meetingProp.intId)
// do nothing
m.actorRef ! new InitializeMeeting(m.mProps.meetingID, m.mProps.recorded)
}
case Some(m) => {
log.info("Meeting already created. meetingID={}", msg.mProps.meetingID)
// do nothing
}
}
}
private def handleGetAllMeetingsRequest(msg: GetAllMeetingsRequest) {
val len = meetings.keys.size
var currPosition = len - 1
var resultArray: Array[MeetingInfo] = new Array[MeetingInfo](len)
meetings.values.foreach(m => {
val id = m.mProps.meetingID
val duration = m.mProps.duration
val name = m.mProps.meetingName
val recorded = m.mProps.recorded
val voiceBridge = m.mProps.voiceBridge
val info = new MeetingInfo(id, name, recorded, voiceBridge, duration)
resultArray(currPosition) = info
currPosition = currPosition - 1
val html5clientRequesterID = "nodeJSapp"
//send the users
eventBus.publish(BigBlueButtonEvent(id, new GetUsers(id, html5clientRequesterID)))
//send the presentation
eventBus.publish(BigBlueButtonEvent(id, new GetPresentationInfo(id, html5clientRequesterID, html5clientRequesterID)))
//send chat history
eventBus.publish(BigBlueButtonEvent(id, new GetChatHistoryRequest(id, html5clientRequesterID, html5clientRequesterID)))
//send lock settings
eventBus.publish(BigBlueButtonEvent(id, new GetLockSettings(id, html5clientRequesterID)))
//send desktop sharing info
eventBus.publish(BigBlueButtonEvent(id, new DeskShareGetDeskShareInfoRequest(id, html5clientRequesterID, html5clientRequesterID)))
// send captions
eventBus.publish(BigBlueButtonEvent(id, new SendCaptionHistoryRequest(id, html5clientRequesterID)))
private def handleGetAllMeetingsReqMsg(msg: GetAllMeetingsReqMsg): Unit = {
RunningMeetings.meetings(meetings).foreach(m => {
m.actorRef ! msg
})
}
outGW.send(new GetAllMeetingsReply(resultArray))
private def handleCheckAlivePingSysMsg(msg: CheckAlivePingSysMsg): Unit = {
val event = MsgBuilder.buildCheckAlivePingSysMsg(msg.body.system, msg.body.timestamp)
outGW.send(event)
}
private def handleDestroyMeeting(msg: DestroyMeetingInternalMsg): Unit = {
for {
m <- RunningMeetings.findWithId(meetings, msg.meetingId)
m2 <- RunningMeetings.remove(meetings, msg.meetingId)
} yield {
/** Unsubscribe to meeting and voice events. **/
eventBus.unsubscribe(m.actorRef, m.props.meetingProp.intId)
eventBus.unsubscribe(m.actorRef, m.props.voiceProp.voiceConf)
eventBus.unsubscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
bbbMsgBus.unsubscribe(m.actorRef, m.props.meetingProp.intId)
bbbMsgBus.unsubscribe(m.actorRef, m.props.voiceProp.voiceConf)
bbbMsgBus.unsubscribe(m.actorRef, m.props.screenshareProps.screenshareConf)
// Delay sending DisconnectAllUsers to allow messages to reach the client
// before the connections are closed.
context.system.scheduler.scheduleOnce(Duration.create(2500, TimeUnit.MILLISECONDS)) {
// Disconnect all clients
val disconnectEvnt = MsgBuilder.buildDisconnectAllClientsSysMsg(msg.meetingId, "meeting-destroyed")
m2.outMsgRouter.send(disconnectEvnt)
val stopTranscodersCmd = MsgBuilder.buildStopMeetingTranscodersSysCmdMsg(msg.meetingId)
m2.outMsgRouter.send(stopTranscodersCmd)
log.info("Destroyed meetingId={}", msg.meetingId)
val destroyedEvent = MsgBuilder.buildMeetingDestroyedEvtMsg(msg.meetingId)
m2.outMsgRouter.send(destroyedEvent)
// Stop the meeting actor.
context.stop(m.actorRef)
}
}
}
}

View File

@ -2,58 +2,48 @@ package org.bigbluebutton.core
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api._
import scala.collection.JavaConversions._
import java.util.ArrayList
import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.core.apps.Page
import org.bigbluebutton.core.apps.Presentation
import akka.actor.ActorSystem
import org.bigbluebutton.core.apps.AnnotationVO
import akka.pattern.{ ask, pipe }
import akka.util.Timeout
import scala.concurrent.duration._
import scala.util.Success
import scala.util.Failure
import org.bigbluebutton.core.service.recorder.RecorderApplication
import org.bigbluebutton.common.messages.IBigBlueButtonMessage
import org.bigbluebutton.common.messages.StartCustomPollRequestMessage
import org.bigbluebutton.common.messages.PubSubPingMessage
import org.bigbluebutton.messages._
import org.bigbluebutton.messages.payload._
import akka.event.Logging
import spray.json.JsonParser
import org.bigbluebutton.SystemConfiguration
import scala.collection.JavaConverters
class BigBlueButtonInGW(
val system: ActorSystem,
eventBus: IncomingEventBus,
outGW: OutMessageGateway,
val red5DeskShareIP: String,
val red5DeskShareApp: String) extends IBigBlueButtonInGW {
eventBus: InternalEventBus,
bbbMsgBus: BbbMsgRouterEventBus,
outGW: OutMessageGateway
) extends IBigBlueButtonInGW with SystemConfiguration {
val log = Logging(system, getClass)
val bbbActor = system.actorOf(BigBlueButtonActor.props(system, eventBus, outGW), "bigbluebutton-actor")
val bbbActor = system.actorOf(BigBlueButtonActor.props(system, eventBus, bbbMsgBus, outGW), "bigbluebutton-actor")
eventBus.subscribe(bbbActor, meetingManagerChannel)
/** For OLD Messaged **/
eventBus.subscribe(bbbActor, "meeting-manager")
def handleBigBlueButtonMessage(message: IBigBlueButtonMessage) {
message match {
case msg: StartCustomPollRequestMessage => {
eventBus.publish(
BigBlueButtonEvent(
msg.payload.meetingId,
new StartCustomPollRequest(
msg.payload.meetingId,
msg.payload.requesterId,
msg.payload.pollType,
msg.payload.answers)))
}
case msg: PubSubPingMessage => {
eventBus.publish(
BigBlueButtonEvent(
"meeting-manager",
new PubSubPing(msg.payload.system, msg.payload.timestamp)))
BigBlueButtonEvent("meeting-manager", new PubSubPing(msg.payload.system, msg.payload.timestamp))
)
}
case msg: CreateMeetingRequest => {
/*val policy = msg.payload.guestPolicy.toUpperCase() match {
case "ALWAYS_ACCEPT" => GuestPolicyType.ALWAYS_ACCEPT
case "ALWAYS_DENY" => GuestPolicyType.ALWAYS_DENY
case "ASK_MODERATOR" => GuestPolicyType.ASK_MODERATOR
//default
case undef => GuestPolicyType.ASK_MODERATOR
}*/
/*
val mProps = new MeetingProperties(
msg.payload.id,
msg.payload.externalId,
@ -72,38 +62,26 @@ class BigBlueButtonInGW(
msg.payload.createDate,
red5DeskShareIP, red5DeskShareApp,
msg.payload.isBreakout,
msg.payload.sequence)
msg.payload.sequence,
mapAsScalaMap(msg.payload.metadata).toMap, // Convert to scala immutable map
policy
)
eventBus.publish(BigBlueButtonEvent("meeting-manager", new CreateMeeting(msg.payload.id, mProps)))
*/
}
}
}
def handleJsonMessage(json: String) {
JsonMessageDecoder.decode(json) match {
case Some(validMsg) => forwardMessage(validMsg)
case None => log.error("Unhandled json message: {}", json)
}
}
def forwardMessage(msg: InMessage) = {
msg match {
case m: BreakoutRoomsListMessage => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: CreateBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: RequestBreakoutJoinURLInMessage => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: TransferUserToMeetingRequest => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case m: EndAllBreakoutRooms => eventBus.publish(BigBlueButtonEvent(m.meetingId, m))
case _ => log.error("Unhandled message: {}", msg)
}
}
def destroyMeeting(meetingID: String) {
forwardMessage(new EndAllBreakoutRooms(meetingID))
eventBus.publish(
BigBlueButtonEvent(
"meeting-manager",
new DestroyMeeting(
meetingID)))
new DestroyMeetingInternalMsg(
meetingID
)
)
)
}
def getAllMeetings(meetingID: String) {
@ -114,10 +92,6 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent("meeting-manager", new KeepAliveMessage(aliveId)))
}
def lockSettings(meetingID: String, locked: java.lang.Boolean,
lockSettings: java.util.Map[String, java.lang.Boolean]) {
}
def statusMeetingAudit(meetingID: String) {
}
@ -130,80 +104,15 @@ class BigBlueButtonInGW(
}
def activityResponse(meetingId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new ActivityResponse(meetingId)))
}
/**
* ***********************************************************
* Message Interface for Users
* ***********************************************************
*/
def validateAuthToken(meetingId: String, userId: String, token: String, correlationId: String, sessionId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new ValidateAuthToken(meetingId, userId, token, correlationId, sessionId)))
}
def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String, authToken: String, avatarURL: String): Unit = {
val userRole = if (role == "MODERATOR") Role.MODERATOR else Role.VIEWER
eventBus.publish(BigBlueButtonEvent(meetingID, new RegisterUser(meetingID, userID, name, userRole, extUserID, authToken, avatarURL)))
}
def sendLockSettings(meetingID: String, userId: String, settings: java.util.Map[String, java.lang.Boolean]) {
// Convert java.util.Map to scala.collection.immutable.Map
// settings.mapValues -> convaert java Map to scala mutable Map
// v => v.booleanValue() -> convert java Boolean to Scala Boolean
// toMap -> converts from scala mutable map to scala immutable map
val s = settings.mapValues(v => v.booleanValue() /* convert java Boolean to Scala Boolean */ ).toMap
val disableCam = s.getOrElse("disableCam", false)
val disableMic = s.getOrElse("disableMic", false)
val disablePrivChat = s.getOrElse("disablePrivateChat", false)
val disablePubChat = s.getOrElse("disablePublicChat", false)
val lockedLayout = s.getOrElse("lockedLayout", false)
var lockOnJoin = s.getOrElse("lockOnJoin", false)
var lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
val permissions = new Permissions(disableCam = disableCam,
disableMic = disableMic,
disablePrivChat = disablePrivChat,
disablePubChat = disablePubChat,
lockedLayout = lockedLayout,
lockOnJoin = lockOnJoin,
lockOnJoinConfigurable = lockOnJoinConfigurable)
eventBus.publish(BigBlueButtonEvent(meetingID, new SetLockSettings(meetingID, userId, permissions)))
}
def initLockSettings(meetingID: String, settings: java.util.Map[String, java.lang.Boolean]) {
// Convert java.util.Map to scala.collection.immutable.Map
// settings.mapValues -> convert java Map to scala mutable Map
// v => v.booleanValue() -> convert java Boolean to Scala Boolean
// toMap -> converts from scala mutable map to scala immutable map
val s = settings.mapValues(v => v.booleanValue() /* convert java Boolean to Scala Boolean */ ).toMap
val disableCam = s.getOrElse("disableCam", false)
val disableMic = s.getOrElse("disableMic", false)
val disablePrivChat = s.getOrElse("disablePrivateChat", false)
val disablePubChat = s.getOrElse("disablePublicChat", false)
val lockedLayout = s.getOrElse("lockedLayout", false)
val lockOnJoin = s.getOrElse("lockOnJoin", false)
val lockOnJoinConfigurable = s.getOrElse("lockOnJoinConfigurable", false)
val permissions = new Permissions(disableCam = disableCam,
disableMic = disableMic,
disablePrivChat = disablePrivChat,
disablePubChat = disablePubChat,
lockedLayout = lockedLayout,
lockOnJoin = lockOnJoin,
lockOnJoinConfigurable = lockOnJoinConfigurable)
eventBus.publish(BigBlueButtonEvent(meetingID, new InitLockSettings(meetingID, permissions)))
}
def initAudioSettings(meetingID: String, requesterID: String, muted: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new InitAudioSettings(meetingID, requesterID, muted.booleanValue())))
}
def getLockSettings(meetingId: String, userId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new GetLockSettings(meetingId, userId)))
}
def lockUser(meetingId: String, requesterID: String, lock: Boolean, userId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new LockUserRequest(meetingId, requesterID, userId, lock)))
}
def setRecordingStatus(meetingId: String, userId: String, recording: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingId, new SetRecordingStatus(meetingId, userId, recording.booleanValue())))
@ -213,295 +122,6 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent(meetingId, new GetRecordingStatus(meetingId, userId)))
}
// Users
def userEmojiStatus(meetingId: String, userId: String, emojiStatus: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new UserEmojiStatus(meetingId, userId, emojiStatus)))
}
def ejectUserFromMeeting(meetingId: String, userId: String, ejectedBy: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new EjectUserFromMeeting(meetingId, userId, ejectedBy)))
}
def shareWebcam(meetingId: String, userId: String, stream: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new UserShareWebcam(meetingId, userId, stream)))
}
def unshareWebcam(meetingId: String, userId: String, stream: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new UserUnshareWebcam(meetingId, userId, stream)))
}
def setUserStatus(meetingID: String, userID: String, status: String, value: Object) {
eventBus.publish(BigBlueButtonEvent(meetingID, new ChangeUserStatus(meetingID, userID, status, value)))
}
def getUsers(meetingID: String, requesterID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetUsers(meetingID, requesterID)))
}
def userLeft(meetingID: String, userID: String, sessionId: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, new UserLeaving(meetingID, userID, sessionId)))
}
def userJoin(meetingID: String, userID: String, authToken: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, new UserJoining(meetingID, userID, authToken)))
}
def checkIfAllowedToShareDesktop(meetingID: String, userID: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, AllowUserToShareDesktop(meetingID: String,
userID: String)))
}
def assignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, new AssignPresenter(meetingID, newPresenterID, newPresenterName, assignedBy)))
}
def getCurrentPresenter(meetingID: String, requesterID: String): Unit = {
// do nothing
}
def userConnectedToGlobalAudio(voiceConf: String, userid: String, name: String) {
// we are required to pass the meeting_id as first parameter (just to satisfy trait)
// but it's not used anywhere. That's why we pass voiceConf twice instead
eventBus.publish(BigBlueButtonEvent(voiceConf, new UserConnectedToGlobalAudio(voiceConf, voiceConf, userid, name)))
}
def userDisconnectedFromGlobalAudio(voiceConf: String, userid: String, name: String) {
// we are required to pass the meeting_id as first parameter (just to satisfy trait)
// but it's not used anywhere. That's why we pass voiceConf twice instead
eventBus.publish(BigBlueButtonEvent(voiceConf, new UserDisconnectedFromGlobalAudio(voiceConf, voiceConf, userid, name)))
}
/**
* ************************************************************************************
* Message Interface for Presentation
* ************************************************************************************
*/
def clear(meetingID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new ClearPresentation(meetingID)))
}
def sendConversionUpdate(messageKey: String, meetingId: String, code: String, presentationId: String, presName: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationConversionUpdate(meetingId, messageKey, code, presentationId, presName)))
}
def sendPageCountError(messageKey: String, meetingId: String, code: String, presentationId: String, numberOfPages: Int, maxNumberPages: Int, presName: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationPageCountError(meetingId, messageKey, code, presentationId, numberOfPages, maxNumberPages, presName)))
}
def sendSlideGenerated(messageKey: String, meetingId: String, code: String, presentationId: String, numberOfPages: Int, pagesCompleted: Int, presName: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationSlideGenerated(meetingId, messageKey, code, presentationId, numberOfPages, pagesCompleted, presName)))
}
def generatePresentationPages(presId: String, numPages: Int, presBaseUrl: String): scala.collection.immutable.HashMap[String, Page] = {
var pages = new scala.collection.immutable.HashMap[String, Page]
val baseUrl =
for (i <- 1 to numPages) {
val id = presId + "/" + i
val num = i;
val current = if (i == 1) true else false
val thumbnail = presBaseUrl + "/thumbnail/" + i
val swfUri = presBaseUrl + "/slide/" + i
val txtUri = presBaseUrl + "/textfiles/" + i
val svgUri = presBaseUrl + "/svg/" + i
val p = new Page(id = id, num = num, thumbUri = thumbnail, swfUri = swfUri,
txtUri = txtUri, svgUri = svgUri,
current = current)
pages += (p.id -> p)
}
pages
}
def sendConversionCompleted(messageKey: String, meetingId: String, code: String, presentationId: String, numPages: Int, presName: String, presBaseUrl: String) {
val pages = generatePresentationPages(presentationId, numPages, presBaseUrl)
val presentation = new Presentation(id = presentationId, name = presName, pages = pages)
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationConversionCompleted(meetingId, messageKey, code, presentation)))
}
def removePresentation(meetingID: String, presentationID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new RemovePresentation(meetingID, presentationID)))
}
def getPresentationInfo(meetingID: String, requesterID: String, replyTo: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetPresentationInfo(meetingID, requesterID, replyTo)))
}
def sendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) {
eventBus.publish(BigBlueButtonEvent(meetingID, new SendCursorUpdate(meetingID, xPercent, yPercent)))
}
def resizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) {
eventBus.publish(BigBlueButtonEvent(meetingID, new ResizeAndMoveSlide(meetingID, xOffset, yOffset, widthRatio, heightRatio)))
}
def gotoSlide(meetingID: String, pageId: String) {
// println("**** Forwarding GotoSlide for meeting[" + meetingID + "] ****")
eventBus.publish(BigBlueButtonEvent(meetingID, new GotoSlide(meetingID, pageId)))
}
def sharePresentation(meetingID: String, presentationID: String, share: Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new SharePresentation(meetingID, presentationID, share)))
}
def getSlideInfo(meetingID: String, requesterID: String, replyTo: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetSlideInfo(meetingID, requesterID, replyTo)))
}
/**
* ***********************************************************************
* Message Interface for Layout
* *******************************************************************
*/
def getCurrentLayout(meetingID: String, requesterID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetCurrentLayoutRequest(meetingID, requesterID)))
}
def broadcastLayout(meetingID: String, requesterID: String, layout: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new BroadcastLayoutRequest(meetingID, requesterID, layout)))
}
def lockLayout(meetingId: String, setById: String, lock: Boolean, viewersOnly: Boolean, layout: String) {
if (layout != null) {
eventBus.publish(BigBlueButtonEvent(meetingId, new LockLayoutRequest(meetingId, setById, lock, viewersOnly, Some(layout))))
} else {
eventBus.publish(BigBlueButtonEvent(meetingId, new LockLayoutRequest(meetingId, setById, lock, viewersOnly, None)))
}
}
/**
* *******************************************************************
* Message Interface for Chat
* *****************************************************************
*/
def getChatHistory(meetingID: String, requesterID: String, replyTo: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetChatHistoryRequest(meetingID, requesterID, replyTo)))
}
def sendPublicMessage(meetingID: String, requesterID: String, message: java.util.Map[String, String]) {
// Convert java Map to Scala Map, then convert Mutable map to immutable map
eventBus.publish(BigBlueButtonEvent(meetingID, new SendPublicMessageRequest(meetingID, requesterID, mapAsScalaMap(message).toMap)))
}
def sendPrivateMessage(meetingID: String, requesterID: String, message: java.util.Map[String, String]) {
eventBus.publish(BigBlueButtonEvent(meetingID, new SendPrivateMessageRequest(meetingID, requesterID, mapAsScalaMap(message).toMap)))
}
/**
* *******************************************************************
* Message Interface for Whiteboard
* *****************************************************************
*/
private def buildAnnotation(annotation: scala.collection.mutable.Map[String, Object]): Option[AnnotationVO] = {
var shape: Option[AnnotationVO] = None
val id = annotation.getOrElse("id", null).asInstanceOf[String]
val shapeType = annotation.getOrElse("type", null).asInstanceOf[String]
val status = annotation.getOrElse("status", null).asInstanceOf[String]
val wbId = annotation.getOrElse("whiteboardId", null).asInstanceOf[String]
// println("** GOT ANNOTATION status[" + status + "] shape=[" + shapeType + "]");
if (id != null && shapeType != null && status != null && wbId != null) {
shape = Some(new AnnotationVO(id, status, shapeType, annotation.toMap, wbId))
}
shape
}
def sendWhiteboardAnnotation(meetingID: String, requesterID: String, annotation: java.util.Map[String, Object]) {
val ann: scala.collection.mutable.Map[String, Object] = mapAsScalaMap(annotation)
buildAnnotation(ann) match {
case Some(shape) => {
eventBus.publish(BigBlueButtonEvent(meetingID, new SendWhiteboardAnnotationRequest(meetingID, requesterID, shape)))
}
case None => // do nothing
}
}
def requestWhiteboardAnnotationHistory(meetingID: String, requesterID: String, whiteboardId: String, replyTo: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new GetWhiteboardShapesRequest(meetingID, requesterID, whiteboardId, replyTo)))
}
def clearWhiteboard(meetingID: String, requesterID: String, whiteboardId: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new ClearWhiteboardRequest(meetingID, requesterID, whiteboardId)))
}
def undoWhiteboard(meetingID: String, requesterID: String, whiteboardId: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new UndoWhiteboardRequest(meetingID, requesterID, whiteboardId)))
}
def enableWhiteboard(meetingID: String, requesterID: String, enable: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new EnableWhiteboardRequest(meetingID, requesterID, enable)))
}
def isWhiteboardEnabled(meetingID: String, requesterID: String, replyTo: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new IsWhiteboardEnabledRequest(meetingID, requesterID, replyTo)))
}
/**
* *******************************************************************
* Message Interface for Voice
* *****************************************************************
*/
def muteAllExceptPresenter(meetingID: String, requesterID: String, mute: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new MuteAllExceptPresenterRequest(meetingID, requesterID, mute)))
}
def muteAllUsers(meetingID: String, requesterID: String, mute: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new MuteMeetingRequest(meetingID, requesterID, mute)))
}
def isMeetingMuted(meetingID: String, requesterID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new IsMeetingMutedRequest(meetingID, requesterID)))
}
def muteUser(meetingID: String, requesterID: String, userID: String, mute: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new MuteUserRequest(meetingID, requesterID, userID, mute)))
}
def lockMuteUser(meetingID: String, requesterID: String, userID: String, lock: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(meetingID, new LockUserRequest(meetingID, requesterID, userID, lock)))
}
def ejectUserFromVoice(meetingId: String, userId: String, ejectedBy: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new EjectUserFromVoiceRequest(meetingId, userId, ejectedBy)))
}
def voiceUserJoined(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String,
callerIdNum: String, muted: java.lang.Boolean, avatarURL: String, talking: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, userId, callerIdName,
callerIdNum, muted, talking, avatarURL, false /*hardcode listenOnly to false as the message for listenOnly is ConnectedToGlobalAudio*/ )))
}
def voiceUserLeft(voiceConfId: String, voiceUserId: String) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserLeftVoiceConfMessage(voiceConfId, voiceUserId)))
}
def voiceUserLocked(voiceConfId: String, voiceUserId: String, locked: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserLockedInVoiceConfMessage(voiceConfId, voiceUserId, locked)))
}
def voiceUserMuted(voiceConfId: String, voiceUserId: String, muted: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserMutedInVoiceConfMessage(voiceConfId, voiceUserId, muted)))
}
def voiceUserTalking(voiceConfId: String, voiceUserId: String, talking: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new UserTalkingInVoiceConfMessage(voiceConfId, voiceUserId, talking)))
}
def voiceRecording(voiceConfId: String, recordingFile: String, timestamp: String, recording: java.lang.Boolean) {
eventBus.publish(BigBlueButtonEvent(voiceConfId, new VoiceConfRecordingStartedMessage(voiceConfId, recordingFile, recording, timestamp)))
}
/**
* *******************************************************************
* Message Interface for DeskShare
@ -529,43 +149,4 @@ class BigBlueButtonInGW(
def deskShareGetInfoRequest(meetingId: String, requesterId: String, replyTo: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingId, new DeskShareGetDeskShareInfoRequest(meetingId, requesterId, replyTo)))
}
// Polling
def votePoll(meetingId: String, userId: String, pollId: String, questionId: Integer, answerId: Integer) {
eventBus.publish(BigBlueButtonEvent(meetingId, new RespondToPollRequest(meetingId, userId, pollId, questionId, answerId)))
}
def startPoll(meetingId: String, requesterId: String, pollId: String, pollType: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new StartPollRequest(meetingId, requesterId, pollType)))
}
def stopPoll(meetingId: String, userId: String, pollId: String) {
eventBus.publish(BigBlueButtonEvent(meetingId, new StopPollRequest(meetingId, userId)))
}
def showPollResult(meetingId: String, requesterId: String, pollId: String, show: java.lang.Boolean) {
if (show) {
eventBus.publish(BigBlueButtonEvent(meetingId, new ShowPollResultRequest(meetingId, requesterId, pollId)))
} else {
eventBus.publish(BigBlueButtonEvent(meetingId, new HidePollResultRequest(meetingId, requesterId, pollId)))
}
}
/**
* *******************************************************************
* Message Interface for Caption
* *****************************************************************
*/
def sendCaptionHistory(meetingID: String, requesterID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new SendCaptionHistoryRequest(meetingID, requesterID)))
}
def updateCaptionOwner(meetingID: String, locale: String, localeCode: String, ownerID: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new UpdateCaptionOwnerRequest(meetingID, locale, localeCode, ownerID)))
}
def editCaptionHistory(meetingID: String, userID: String, startIndex: Integer, endIndex: Integer, locale: String, localeCode: String, text: String) {
eventBus.publish(BigBlueButtonEvent(meetingID, new EditCaptionHistoryRequest(meetingID, userID, startIndex, endIndex, locale, localeCode, text)))
}
}

View File

@ -1,78 +0,0 @@
package org.bigbluebutton.core
import scala.util.{ Try, Success, Failure }
import spray.json.{ JsObject, JsonParser, DeserializationException }
import org.parboiled.errors.ParsingException
import org.bigbluebutton.core.api._
import org.bigbluebutton.messages._
object JsonMessageDecoder {
import org.bigbluebutton.core.UserMessagesProtocol._
import spray.json._
def header(msg: JsObject): InMessageHeader = {
msg.fields.get("header") match {
case Some(header) =>
header.convertTo[InMessageHeader]
case None =>
throw MessageProcessException("Cannot get payload information: [" + msg + "]")
}
}
def payload(msg: JsObject): JsObject = {
msg.fields.get("payload") match {
case Some(payload) =>
payload.asJsObject
case None =>
throw MessageProcessException("Cannot get payload information: [" + msg + "]")
}
}
def toJsObject(msg: String): JsObject = {
try {
JsonParser(msg).asJsObject
} catch {
case e: ParsingException => {
throw MessageProcessException("Cannot parse JSON message: [" + msg + "]")
}
}
}
def unmarshall(jsonMsg: String): Try[InMessage] = {
for {
jsonObj <- Try(toJsObject(jsonMsg))
header <- Try(header(jsonObj))
payload <- Try(payload(jsonObj))
msg = InHeaderAndJsonPayload(header, payload)
inmsg <- Try(convertMessage(msg))
} yield inmsg
}
def decode(json: String): Option[InMessage] = {
unmarshall(json) match {
case Success(validMsg) => Some(validMsg)
case Failure(ex) => None
}
}
def convertMessage(msg: InHeaderAndJsonPayload): InMessage = {
msg.header.name match {
case GetBreakoutRoomsList.NAME => {
msg.payload.convertTo[BreakoutRoomsListMessage]
}
case CreateBreakoutRoomsRequest.NAME => {
msg.payload.convertTo[CreateBreakoutRooms]
}
case RequestBreakoutJoinURL.NAME => {
msg.payload.convertTo[RequestBreakoutJoinURLInMessage]
}
case ListenInOnBreakout.NAME => {
msg.payload.convertTo[TransferUserToMeetingRequest]
}
case EndAllBreakoutRoomsRequest.NAME => {
msg.payload.convertTo[EndAllBreakoutRooms]
}
case _ => throw MessageProcessException("Cannot parse JSON message: [" + msg + "]")
}
}
}

View File

@ -1,114 +0,0 @@
package org.bigbluebutton.core
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.ActorLogging
import akka.actor.Props
import org.bigbluebutton.core.api._
import org.bigbluebutton.common.messages.MessagingConstants
import org.bigbluebutton.core.pubsub.senders.ChatMessageToJsonConverter
import org.bigbluebutton.common.messages.StartRecordingVoiceConfRequestMessage
import org.bigbluebutton.common.messages.StopRecordingVoiceConfRequestMessage
import org.bigbluebutton.core.pubsub.senders.MeetingMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.PesentationMessageToJsonConverter
import org.bigbluebutton.common.messages.GetPresentationInfoReplyMessage
import org.bigbluebutton.common.messages.PresentationRemovedMessage
import org.bigbluebutton.core.apps.Page
import collection.JavaConverters._
import scala.collection.JavaConversions._
import org.bigbluebutton.core.apps.SimplePollResultOutVO
import org.bigbluebutton.core.apps.SimplePollOutVO
import org.bigbluebutton.core.pubsub.senders.UsersMessageToJsonConverter
import org.bigbluebutton.common.messages._
import org.bigbluebutton.core.pubsub.senders.WhiteboardMessageToJsonConverter
import org.bigbluebutton.common.converters.ToJsonEncoder
import org.bigbluebutton.common.messages.payload._
import org.bigbluebutton.common.messages._
import org.bigbluebutton.messages.payload._
import org.bigbluebutton.messages._
object JsonMessageSenderActor {
def props(msgSender: MessageSender): Props =
Props(classOf[JsonMessageSenderActor], msgSender)
}
class JsonMessageSenderActor(val service: MessageSender)
extends Actor with ActorLogging {
def receive = {
// Breakout
case msg: CreateBreakoutRoom => handleCreateBreakoutRoom(msg)
case msg: EndBreakoutRoom => handleEndBreakoutRoom(msg)
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsList(msg)
case msg: BreakoutRoomJoinURLOutMessage => handleBreakoutRoomJoinURL(msg)
case msg: BreakoutRoomStartedOutMessage => handleBreakoutRoomStarted(msg)
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEnded(msg)
case msg: UpdateBreakoutUsersOutMessage => handleUpdateBreakoutUsers(msg)
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
case _ => // do nothing
}
// Breakout
private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) {
val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, msg.breakout.externalMeetingId, msg.breakout.name, msg.breakout.sequence)
val request = new BreakoutRoomStarted(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
private def handleBreakoutRoomEnded(msg: BreakoutRoomEndedOutMessage) {
val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.meetingId, "", "", 0)
val request = new BreakoutRoomClosed(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
private def handleUpdateBreakoutUsers(msg: UpdateBreakoutUsersOutMessage) {
val users = new java.util.ArrayList[BreakoutUserPayload]()
msg.users.foreach(x => users.add(new BreakoutUserPayload(x.id, x.name)))
val payload = new UpdateBreakoutUsersPayload(msg.parentMeetingId, msg.breakoutMeetingId, users)
val request = new UpdateBreakoutUsers(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleMeetingTimeRemainingUpdate(msg: MeetingTimeRemainingUpdate) {
val payload = new MeetingTimeRemainingPayload(msg.meetingId, msg.timeRemaining)
val request = new TimeRemainingUpdate(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleMeetingTimeRemainingUpdate(msg: BreakoutRoomsTimeRemainingUpdateOutMessage) {
val payload = new BreakoutRoomsTimeRemainingPayload(msg.meetingId, msg.timeRemaining)
val request = new BreakoutRoomsTimeRemainingUpdate(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleBreakoutRoomsList(msg: BreakoutRoomsListOutMessage) {
val rooms = new java.util.ArrayList[BreakoutRoomPayload]()
msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.meetingId, r.externalMeetingId, r.name, r.sequence)))
val payload = new BreakoutRoomsListPayload(msg.meetingId, rooms, msg.roomsReady)
val request = new BreakoutRoomsList(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleCreateBreakoutRoom(msg: CreateBreakoutRoom) {
val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutMeetingId, msg.room.parentId, msg.room.name,
msg.room.sequence, msg.room.voiceConfId, msg.room.viewerPassword, msg.room.moderatorPassword,
msg.room.durationInMinutes, msg.room.sourcePresentationId, msg.room.sourcePresentationSlide, msg.room.record)
val request = new CreateBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
private def handleEndBreakoutRoom(msg: EndBreakoutRoom) {
val payload = new EndBreakoutRoomRequestPayload(msg.breakoutMeetingId)
val request = new EndBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
}
def handleBreakoutRoomJoinURL(msg: BreakoutRoomJoinURLOutMessage) {
val payload = new BreakoutRoomJoinURLPayload(msg.parentMeetingId,
msg.breakoutMeetingId, msg.userId, msg.redirectJoinURL, msg.noRedirectJoinURL)
val request = new BreakoutRoomJoinURL(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
}
}

View File

@ -1,249 +0,0 @@
package org.bigbluebutton.core
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.apps._
import org.bigbluebutton.core.bus.IncomingEventBus
import akka.actor.ActorContext
import akka.event.Logging
class LiveMeeting(val mProps: MeetingProperties,
val eventBus: IncomingEventBus,
val outGW: OutMessageGateway,
val chatModel: ChatModel,
val layoutModel: LayoutModel,
val meetingModel: MeetingModel,
val usersModel: UsersModel,
val pollModel: PollModel,
val wbModel: WhiteboardModel,
val presModel: PresentationModel,
val breakoutModel: BreakoutRoomModel,
val captionModel: CaptionModel)(implicit val context: ActorContext)
extends UsersApp with PresentationApp
with LayoutApp with ChatApp with WhiteboardApp with PollApp
with BreakoutRoomApp with CaptionApp {
val log = Logging(context.system, getClass)
def hasMeetingEnded(): Boolean = {
meetingModel.hasMeetingEnded()
}
def webUserJoined() {
if (usersModel.numWebUsers > 0) {
meetingModel.resetLastWebUserLeftOn()
}
}
def startRecordingIfAutoStart() {
if (mProps.recorded && !meetingModel.isRecording() && mProps.autoStartRecording && usersModel.numWebUsers == 1) {
log.info("Auto start recording. meetingId={}", mProps.meetingID)
meetingModel.recordingStarted()
outGW.send(new RecordingStatusChanged(mProps.meetingID, mProps.recorded, "system", meetingModel.isRecording()))
}
}
def stopAutoStartedRecording() {
if (mProps.recorded && meetingModel.isRecording() && mProps.autoStartRecording && usersModel.numWebUsers == 0) {
log.info("Last web user left. Auto stopping recording. meetingId={}", mProps.meetingID)
meetingModel.recordingStopped()
outGW.send(new RecordingStatusChanged(mProps.meetingID, mProps.recorded, "system", meetingModel.isRecording()))
}
}
def startCheckingIfWeNeedToEndVoiceConf() {
if (usersModel.numWebUsers == 0 && !mProps.isBreakout) {
meetingModel.lastWebUserLeft()
log.debug("MonitorNumberOfWebUsers started for meeting [" + mProps.meetingID + "]")
}
}
def sendTimeRemainingNotice() {
val now = timeNowInSeconds
if (mProps.duration > 0 && (((meetingModel.startedOn + mProps.duration) - now) < 15)) {
// log.warning("MEETING WILL END IN 15 MINUTES!!!!")
}
}
def handleMonitorNumberOfWebUsers(msg: MonitorNumberOfUsers) {
if (usersModel.numWebUsers == 0 && meetingModel.lastWebUserLeftOn > 0) {
if (timeNowInMinutes - meetingModel.lastWebUserLeftOn > 2) {
log.info("Empty meeting. Ejecting all users from voice. meetingId={}", mProps.meetingID)
outGW.send(new EjectAllVoiceUsers(mProps.meetingID, mProps.recorded, mProps.voiceBridge))
}
}
}
def handleSendTimeRemainingUpdate(msg: SendTimeRemainingUpdate) {
if (mProps.duration > 0) {
val endMeetingTime = meetingModel.startedOn + (mProps.duration * 60)
val timeRemaining = endMeetingTime - timeNowInSeconds
outGW.send(new MeetingTimeRemainingUpdate(mProps.meetingID, mProps.recorded, timeRemaining.toInt))
}
if (!mProps.isBreakout && breakoutModel.getRooms().length > 0) {
val room = breakoutModel.getRooms()(0);
val endMeetingTime = meetingModel.breakoutRoomsStartedOn + (meetingModel.breakoutRoomsdurationInMinutes * 60)
val timeRemaining = endMeetingTime - timeNowInSeconds
outGW.send(new BreakoutRoomsTimeRemainingUpdateOutMessage(mProps.meetingID, mProps.recorded, timeRemaining.toInt))
} else if (meetingModel.breakoutRoomsStartedOn != 0) {
meetingModel.breakoutRoomsdurationInMinutes = 0;
meetingModel.breakoutRoomsStartedOn = 0;
}
}
def handleExtendMeetingDuration(msg: ExtendMeetingDuration) {
}
def timeNowInMinutes(): Long = {
TimeUnit.NANOSECONDS.toMinutes(System.nanoTime())
}
def timeNowInSeconds(): Long = {
TimeUnit.NANOSECONDS.toSeconds(System.nanoTime())
}
def sendMeetingHasEnded(userId: String) {
outGW.send(new MeetingHasEnded(mProps.meetingID, userId))
outGW.send(new DisconnectUser(mProps.meetingID, userId))
}
def handleEndMeeting(msg: EndMeeting) {
// Broadcast users the meeting will end
outGW.send(new MeetingEnding(msg.meetingId))
meetingModel.meetingHasEnded
outGW.send(new MeetingEnded(msg.meetingId, mProps.recorded, mProps.voiceBridge))
}
def handleAllowUserToShareDesktop(msg: AllowUserToShareDesktop): Unit = {
usersModel.getCurrentPresenter() match {
case Some(curPres) => {
val allowed = msg.userID equals (curPres.userID)
outGW.send(AllowUserToShareDesktopOut(msg.meetingID, msg.userID, allowed))
}
case None => // do nothing
}
}
def handleVoiceConfRecordingStartedMessage(msg: VoiceConfRecordingStartedMessage) {
if (msg.recording) {
meetingModel.setVoiceRecordingFilename(msg.recordStream)
outGW.send(new VoiceRecordingStarted(mProps.meetingID, mProps.recorded, msg.recordStream, msg.timestamp, mProps.voiceBridge))
} else {
meetingModel.setVoiceRecordingFilename("")
outGW.send(new VoiceRecordingStopped(mProps.meetingID, mProps.recorded, msg.recordStream, msg.timestamp, mProps.voiceBridge))
}
}
def handleSetRecordingStatus(msg: SetRecordingStatus) {
log.info("Change recording status. meetingId=" + mProps.meetingID + " recording=" + msg.recording)
if (mProps.allowStartStopRecording && meetingModel.isRecording() != msg.recording) {
if (msg.recording) {
meetingModel.recordingStarted()
} else {
meetingModel.recordingStopped()
}
outGW.send(new RecordingStatusChanged(mProps.meetingID, mProps.recorded, msg.userId, msg.recording))
}
}
def handleGetRecordingStatus(msg: GetRecordingStatus) {
outGW.send(new GetRecordingStatusReply(mProps.meetingID, mProps.recorded, msg.userId, meetingModel.isRecording().booleanValue()))
}
def lockLayout(lock: Boolean) {
meetingModel.lockLayout(lock)
}
def newPermissions(np: Permissions) {
meetingModel.setPermissions(np)
}
def permissionsEqual(other: Permissions): Boolean = {
meetingModel.permissionsEqual(other)
}
// WebRTC Desktop Sharing
def handleDeskShareStartedRequest(msg: DeskShareStartedRequest): Unit = {
log.info("handleDeskShareStartedRequest: dsStarted=" + meetingModel.getDeskShareStarted())
if (!meetingModel.getDeskShareStarted()) {
val timestamp = System.currentTimeMillis().toString
val streamPath = "rtmp://" + mProps.red5DeskShareIP + "/" + mProps.red5DeskShareApp +
"/" + mProps.meetingID + "/" + mProps.meetingID + "-" + timestamp
log.info("handleDeskShareStartedRequest: streamPath=" + streamPath)
// Tell FreeSwitch to broadcast to RTMP
outGW.send(new DeskShareStartRTMPBroadcast(msg.conferenceName, streamPath))
meetingModel.setDeskShareStarted(true)
}
}
def handleDeskShareStoppedRequest(msg: DeskShareStoppedRequest): Unit = {
log.info("handleDeskShareStoppedRequest: dsStarted=" + meetingModel.getDeskShareStarted() +
" URL:" + meetingModel.getRTMPBroadcastingUrl())
// Tell FreeSwitch to stop broadcasting to RTMP
outGW.send(new DeskShareStopRTMPBroadcast(msg.conferenceName, meetingModel.getRTMPBroadcastingUrl()))
meetingModel.setDeskShareStarted(false)
}
def handleDeskShareRTMPBroadcastStartedRequest(msg: DeskShareRTMPBroadcastStartedRequest): Unit = {
log.info("handleDeskShareRTMPBroadcastStartedRequest: isBroadcastingRTMP=" + meetingModel.isBroadcastingRTMP() +
" URL:" + meetingModel.getRTMPBroadcastingUrl())
// only valid if not broadcasting yet
if (!meetingModel.isBroadcastingRTMP()) {
meetingModel.setRTMPBroadcastingUrl(msg.streamname)
meetingModel.broadcastingRTMPStarted()
meetingModel.setDesktopShareVideoWidth(msg.videoWidth)
meetingModel.setDesktopShareVideoHeight(msg.videoHeight)
log.info("START broadcast ALLOWED when isBroadcastingRTMP=false")
// Notify viewers in the meeting that there's an rtmp stream to view
outGW.send(new DeskShareNotifyViewersRTMP(mProps.meetingID, msg.streamname, msg.videoWidth, msg.videoHeight, true))
} else {
log.info("START broadcast NOT ALLOWED when isBroadcastingRTMP=true")
}
}
def handleDeskShareRTMPBroadcastStoppedRequest(msg: DeskShareRTMPBroadcastStoppedRequest): Unit = {
log.info("handleDeskShareRTMPBroadcastStoppedRequest: isBroadcastingRTMP=" + meetingModel
.isBroadcastingRTMP() + " URL:" + meetingModel.getRTMPBroadcastingUrl())
// only valid if currently broadcasting
if (meetingModel.isBroadcastingRTMP()) {
log.info("STOP broadcast ALLOWED when isBroadcastingRTMP=true")
meetingModel.broadcastingRTMPStopped()
// notify viewers that RTMP broadcast stopped
outGW.send(new DeskShareNotifyViewersRTMP(mProps.meetingID, meetingModel.getRTMPBroadcastingUrl(),
msg.videoWidth, msg.videoHeight, false))
} else {
log.info("STOP broadcast NOT ALLOWED when isBroadcastingRTMP=false")
}
}
def handleDeskShareGetDeskShareInfoRequest(msg: DeskShareGetDeskShareInfoRequest): Unit = {
log.info("handleDeskShareGetDeskShareInfoRequest: " + msg.conferenceName + "isBroadcasting="
+ meetingModel.isBroadcastingRTMP() + " URL:" + meetingModel.getRTMPBroadcastingUrl())
if (meetingModel.isBroadcastingRTMP()) {
// if the meeting has an ongoing WebRTC Deskshare session, send a notification
outGW.send(new DeskShareNotifyASingleViewer(mProps.meetingID, msg.requesterID, meetingModel.getRTMPBroadcastingUrl(),
meetingModel.getDesktopShareVideoWidth(), meetingModel.getDesktopShareVideoHeight(), true))
}
}
}

View File

@ -1,191 +0,0 @@
package org.bigbluebutton.core
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.ActorLogging
import akka.actor.Props
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api._
import java.util.concurrent.TimeUnit
import org.bigbluebutton.core.util._
import scala.concurrent.duration._
import org.bigbluebutton.core.apps.{ PollApp, UsersApp, PresentationApp, LayoutApp, ChatApp, WhiteboardApp, CaptionApp }
import org.bigbluebutton.core.apps.{ ChatModel, LayoutModel, UsersModel, PollModel, WhiteboardModel, CaptionModel }
import org.bigbluebutton.core.apps.PresentationModel
import org.bigbluebutton.core.apps.BreakoutRoomApp
import org.bigbluebutton.core.apps.BreakoutRoomModel
object MeetingActorInternal {
def props(mProps: MeetingProperties,
eventBus: IncomingEventBus,
outGW: OutMessageGateway): Props =
Props(classOf[MeetingActorInternal], mProps, eventBus, outGW)
}
// This actor is an internal audit actor for each meeting actor that
// periodically sends messages to the meeting actor
class MeetingActorInternal(val mProps: MeetingProperties,
val eventBus: IncomingEventBus, val outGW: OutMessageGateway)
extends Actor with ActorLogging {
import context.dispatcher
context.system.scheduler.schedule(5 seconds, 10 seconds, self, "MonitorNumberOfWebUsers")
// Query to get voice conference users
outGW.send(new GetUsersInVoiceConference(mProps.meetingID, mProps.recorded, mProps.voiceBridge))
if (mProps.isBreakout) {
// This is a breakout room. Inform our parent meeting that we have been successfully created.
eventBus.publish(BigBlueButtonEvent(
mProps.parentMeetingID,
BreakoutRoomCreated(mProps.parentMeetingID, mProps.meetingID)))
}
def receive = {
case "MonitorNumberOfWebUsers" => handleMonitorNumberOfWebUsers()
}
def handleMonitorNumberOfWebUsers() {
eventBus.publish(BigBlueButtonEvent(mProps.meetingID, MonitorNumberOfUsers(mProps.meetingID)))
// Trigger updating users of time remaining on meeting.
eventBus.publish(BigBlueButtonEvent(mProps.meetingID, SendTimeRemainingUpdate(mProps.meetingID)))
if (mProps.isBreakout) {
// This is a breakout room. Update the main meeting with list of users in this breakout room.
eventBus.publish(BigBlueButtonEvent(mProps.meetingID, SendBreakoutUsersUpdate(mProps.meetingID)))
}
}
}
object MeetingActor {
def props(mProps: MeetingProperties,
eventBus: IncomingEventBus,
outGW: OutMessageGateway): Props =
Props(classOf[MeetingActor], mProps, eventBus, outGW)
}
class MeetingActor(val mProps: MeetingProperties,
val eventBus: IncomingEventBus,
val outGW: OutMessageGateway)
extends Actor with ActorLogging {
val chatModel = new ChatModel()
val layoutModel = new LayoutModel()
val meetingModel = new MeetingModel()
val usersModel = new UsersModel()
val pollModel = new PollModel()
val wbModel = new WhiteboardModel()
val presModel = new PresentationModel()
val breakoutModel = new BreakoutRoomModel()
val captionModel = new CaptionModel()
// We extract the meeting handlers into this class so it is
// easy to test.
val liveMeeting = new LiveMeeting(mProps, eventBus, outGW,
chatModel, layoutModel, meetingModel, usersModel, pollModel,
wbModel, presModel, breakoutModel, captionModel)
/**
* Put the internal message injector into another actor so this
* actor is easy to test.
*/
var actorMonitor = context.actorOf(MeetingActorInternal.props(mProps, eventBus, outGW))
def receive = {
case msg: MonitorNumberOfUsers => liveMeeting.handleMonitorNumberOfWebUsers(msg)
case msg: ValidateAuthToken => liveMeeting.handleValidateAuthToken(msg)
case msg: RegisterUser => liveMeeting.handleRegisterUser(msg)
case msg: UserJoinedVoiceConfMessage => liveMeeting.handleUserJoinedVoiceConfMessage(msg)
case msg: UserLeftVoiceConfMessage => liveMeeting.handleUserLeftVoiceConfMessage(msg)
case msg: UserMutedInVoiceConfMessage => liveMeeting.handleUserMutedInVoiceConfMessage(msg)
case msg: UserTalkingInVoiceConfMessage => liveMeeting.handleUserTalkingInVoiceConfMessage(msg)
case msg: VoiceConfRecordingStartedMessage => liveMeeting.handleVoiceConfRecordingStartedMessage(msg)
case msg: UserJoining => liveMeeting.handleUserJoin(msg)
case msg: UserLeaving => liveMeeting.handleUserLeft(msg)
case msg: AssignPresenter => liveMeeting.handleAssignPresenter(msg)
case msg: AllowUserToShareDesktop => liveMeeting.handleAllowUserToShareDesktop(msg)
case msg: GetUsers => liveMeeting.handleGetUsers(msg)
case msg: ChangeUserStatus => liveMeeting.handleChangeUserStatus(msg)
case msg: EjectUserFromMeeting => liveMeeting.handleEjectUserFromMeeting(msg)
case msg: UserEmojiStatus => liveMeeting.handleUserEmojiStatus(msg)
case msg: UserShareWebcam => liveMeeting.handleUserShareWebcam(msg)
case msg: UserUnshareWebcam => liveMeeting.handleUserunshareWebcam(msg)
case msg: MuteMeetingRequest => liveMeeting.handleMuteMeetingRequest(msg)
case msg: MuteAllExceptPresenterRequest => liveMeeting.handleMuteAllExceptPresenterRequest(msg)
case msg: IsMeetingMutedRequest => liveMeeting.handleIsMeetingMutedRequest(msg)
case msg: MuteUserRequest => liveMeeting.handleMuteUserRequest(msg)
case msg: EjectUserFromVoiceRequest => liveMeeting.handleEjectUserRequest(msg)
case msg: TransferUserToMeetingRequest => liveMeeting.handleTransferUserToMeeting(msg)
case msg: SetLockSettings => liveMeeting.handleSetLockSettings(msg)
case msg: GetLockSettings => liveMeeting.handleGetLockSettings(msg)
case msg: LockUserRequest => liveMeeting.handleLockUserRequest(msg)
case msg: InitLockSettings => liveMeeting.handleInitLockSettings(msg)
case msg: InitAudioSettings => liveMeeting.handleInitAudioSettings(msg)
case msg: GetChatHistoryRequest => liveMeeting.handleGetChatHistoryRequest(msg)
case msg: SendPublicMessageRequest => liveMeeting.handleSendPublicMessageRequest(msg)
case msg: SendPrivateMessageRequest => liveMeeting.handleSendPrivateMessageRequest(msg)
case msg: UserConnectedToGlobalAudio => liveMeeting.handleUserConnectedToGlobalAudio(msg)
case msg: UserDisconnectedFromGlobalAudio => liveMeeting.handleUserDisconnectedFromGlobalAudio(msg)
case msg: GetCurrentLayoutRequest => liveMeeting.handleGetCurrentLayoutRequest(msg)
case msg: BroadcastLayoutRequest => liveMeeting.handleBroadcastLayoutRequest(msg)
case msg: InitializeMeeting => liveMeeting.handleInitializeMeeting(msg)
case msg: ClearPresentation => liveMeeting.handleClearPresentation(msg)
case msg: PresentationConversionUpdate => liveMeeting.handlePresentationConversionUpdate(msg)
case msg: PresentationPageCountError => liveMeeting.handlePresentationPageCountError(msg)
case msg: PresentationSlideGenerated => liveMeeting.handlePresentationSlideGenerated(msg)
case msg: PresentationConversionCompleted => liveMeeting.handlePresentationConversionCompleted(msg)
case msg: RemovePresentation => liveMeeting.handleRemovePresentation(msg)
case msg: GetPresentationInfo => liveMeeting.handleGetPresentationInfo(msg)
case msg: SendCursorUpdate => liveMeeting.handleSendCursorUpdate(msg)
case msg: ResizeAndMoveSlide => liveMeeting.handleResizeAndMoveSlide(msg)
case msg: GotoSlide => liveMeeting.handleGotoSlide(msg)
case msg: SharePresentation => liveMeeting.handleSharePresentation(msg)
case msg: GetSlideInfo => liveMeeting.handleGetSlideInfo(msg)
case msg: PreuploadedPresentations => liveMeeting.handlePreuploadedPresentations(msg)
case msg: SendWhiteboardAnnotationRequest => liveMeeting.handleSendWhiteboardAnnotationRequest(msg)
case msg: GetWhiteboardShapesRequest => liveMeeting.handleGetWhiteboardShapesRequest(msg)
case msg: ClearWhiteboardRequest => liveMeeting.handleClearWhiteboardRequest(msg)
case msg: UndoWhiteboardRequest => liveMeeting.handleUndoWhiteboardRequest(msg)
case msg: EnableWhiteboardRequest => liveMeeting.handleEnableWhiteboardRequest(msg)
case msg: IsWhiteboardEnabledRequest => liveMeeting.handleIsWhiteboardEnabledRequest(msg)
case msg: SetRecordingStatus => liveMeeting.handleSetRecordingStatus(msg)
case msg: GetRecordingStatus => liveMeeting.handleGetRecordingStatus(msg)
case msg: StartCustomPollRequest => liveMeeting.handleStartCustomPollRequest(msg)
case msg: StartPollRequest => liveMeeting.handleStartPollRequest(msg)
case msg: StopPollRequest => liveMeeting.handleStopPollRequest(msg)
case msg: ShowPollResultRequest => liveMeeting.handleShowPollResultRequest(msg)
case msg: HidePollResultRequest => liveMeeting.handleHidePollResultRequest(msg)
case msg: RespondToPollRequest => liveMeeting.handleRespondToPollRequest(msg)
case msg: GetPollRequest => liveMeeting.handleGetPollRequest(msg)
case msg: GetCurrentPollRequest => liveMeeting.handleGetCurrentPollRequest(msg)
// Breakout rooms
case msg: BreakoutRoomsListMessage => liveMeeting.handleBreakoutRoomsList(msg)
case msg: CreateBreakoutRooms => liveMeeting.handleCreateBreakoutRooms(msg)
case msg: BreakoutRoomCreated => liveMeeting.handleBreakoutRoomCreated(msg)
case msg: BreakoutRoomEnded => liveMeeting.handleBreakoutRoomEnded(msg)
case msg: RequestBreakoutJoinURLInMessage => liveMeeting.handleRequestBreakoutJoinURL(msg)
case msg: BreakoutRoomUsersUpdate => liveMeeting.handleBreakoutRoomUsersUpdate(msg)
case msg: SendBreakoutUsersUpdate => liveMeeting.handleSendBreakoutUsersUpdate(msg)
case msg: EndAllBreakoutRooms => liveMeeting.handleEndAllBreakoutRooms(msg)
case msg: ExtendMeetingDuration => liveMeeting.handleExtendMeetingDuration(msg)
case msg: SendTimeRemainingUpdate => liveMeeting.handleSendTimeRemainingUpdate(msg)
case msg: EndMeeting => liveMeeting.handleEndMeeting(msg)
// Closed Caption
case msg: SendCaptionHistoryRequest => liveMeeting.handleSendCaptionHistoryRequest(msg)
case msg: UpdateCaptionOwnerRequest => liveMeeting.handleUpdateCaptionOwnerRequest(msg)
case msg: EditCaptionHistoryRequest => liveMeeting.handleEditCaptionHistoryRequest(msg)
case msg: DeskShareStartedRequest => liveMeeting.handleDeskShareStartedRequest(msg)
case msg: DeskShareStoppedRequest => liveMeeting.handleDeskShareStoppedRequest(msg)
case msg: DeskShareRTMPBroadcastStartedRequest => liveMeeting.handleDeskShareRTMPBroadcastStartedRequest(msg)
case msg: DeskShareRTMPBroadcastStoppedRequest => liveMeeting.handleDeskShareRTMPBroadcastStoppedRequest(msg)
case msg: DeskShareGetDeskShareInfoRequest => liveMeeting.handleDeskShareGetDeskShareInfoRequest(msg)
case _ => // do nothing
}
}

View File

@ -1,133 +1,71 @@
package org.bigbluebutton.core
import org.bigbluebutton.core.api.Permissions
import java.util.concurrent.TimeUnit
case object StopMeetingActor
case class MeetingProperties(meetingID: String, externalMeetingID: String, parentMeetingID: String, meetingName: String,
recorded: Boolean, voiceBridge: String, deskshareBridge: String, duration: Int,
autoStartRecording: Boolean, allowStartStopRecording: Boolean, webcamsOnlyForModerator: Boolean,
moderatorPass: String, viewerPass: String, createTime: Long, createDate: String,
red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean, sequence: Int)
case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20,
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
sendNotice: Boolean = true, sent15MinNotice: Boolean = false,
sent10MinNotice: Boolean = false, sent5MinNotice: Boolean = false)
class MeetingModel {
private var audioSettingsInited = false
private var permissionsInited = false
private var permissions = new Permissions()
private var recording = false;
private var broadcastingRTMP = false
private var muted = false;
private var recording = false
private var muted = false
private var meetingEnded = false
private var meetingMuted = false
private var guestPolicySetBy: String = null
private var hasLastWebUserLeft = false
private var lastWebUserLeftOnTimestamp: Long = 0
private var voiceRecordingFilename: String = ""
private var rtmpBroadcastingUrl: String = ""
private var deskShareStarted = false
private var desktopShareVideoWidth = 0
private var desktopShareVideoHeight = 0
private var extension = new MeetingExtensionProp
/*
val startedOn = timeNowInSeconds;
val startedOn = timeNowInSeconds;
var breakoutRoomsStartedOn: Long = 0;
var breakoutRoomsdurationInMinutes: Int = 0;
def resetDesktopSharingParams() = {
broadcastingRTMP = false
deskShareStarted = false
rtmpBroadcastingUrl = ""
desktopShareVideoWidth = 0
desktopShareVideoHeight = 0
}
def getDeskShareStarted(): Boolean = {
return deskShareStarted
}
def setDeskShareStarted(b: Boolean) {
deskShareStarted = b
println("---deskshare status changed to:" + b)
}
def setDesktopShareVideoWidth(videoWidth: Int) {
desktopShareVideoWidth = videoWidth
}
def setDesktopShareVideoHeight(videoHeight: Int) {
desktopShareVideoHeight = videoHeight
}
def getDesktopShareVideoWidth(): Int = {
desktopShareVideoWidth
}
def getDesktopShareVideoHeight(): Int = {
desktopShareVideoHeight
}
def broadcastingRTMPStarted() {
broadcastingRTMP = true
}
def isBroadcastingRTMP(): Boolean = {
broadcastingRTMP
}
def broadcastingRTMPStopped() {
broadcastingRTMP = false
}
def setRTMPBroadcastingUrl(path: String) {
println("---RTMP broadcastUrl changed to:" + path)
rtmpBroadcastingUrl = path
}
def getRTMPBroadcastingUrl(): String = {
rtmpBroadcastingUrl
}
def isExtensionAllowed(): Boolean = extension.numExtensions < extension.maxExtensions
def incNumExtension(): Int = {
if (extension.numExtensions < extension.maxExtensions) {
extension = extension.copy(numExtensions = extension.numExtensions + 1); extension.numExtensions
def isExtensionAllowed(): Boolean = extension.numExtensions < extension.maxExtensions
def incNumExtension(): Int = {
if (extension.numExtensions < extension.maxExtensions) {
extension = extension.copy(numExtensions = extension.numExtensions + 1); extension.numExtensions
}
extension.numExtensions
}
extension.numExtensions
}
def notice15MinutesSent() = extension = extension.copy(sent15MinNotice = true)
def notice10MinutesSent() = extension = extension.copy(sent10MinNotice = true)
def notice5MinutesSent() = extension = extension.copy(sent5MinNotice = true)
def notice15MinutesSent() = extension = extension.copy(sent15MinNotice = true)
def notice10MinutesSent() = extension = extension.copy(sent10MinNotice = true)
def notice5MinutesSent() = extension = extension.copy(sent5MinNotice = true)
def getMeetingExtensionProp(): MeetingExtensionProp = extension
def muteMeeting() = meetingMuted = true
def unmuteMeeting() = meetingMuted = false
def isMeetingMuted(): Boolean = meetingMuted
def recordingStarted() = recording = true
def recordingStopped() = recording = false
def isRecording(): Boolean = recording
def lastWebUserLeft() = lastWebUserLeftOnTimestamp = timeNowInMinutes
def lastWebUserLeftOn(): Long = lastWebUserLeftOnTimestamp
def resetLastWebUserLeftOn() = lastWebUserLeftOnTimestamp = 0
def setVoiceRecordingFilename(path: String) = voiceRecordingFilename = path
def getVoiceRecordingFilename(): String = voiceRecordingFilename
def permisionsInitialized(): Boolean = permissionsInited
def initializePermissions() = permissionsInited = true
def audioSettingsInitialized(): Boolean = audioSettingsInited
def initializeAudioSettings() = audioSettingsInited = true
def permissionsEqual(other: Permissions): Boolean = permissions == other
def lockLayout(lock: Boolean) = permissions = permissions.copy(lockedLayout = lock)
def getPermissions(): Permissions = permissions
def setPermissions(p: Permissions) = permissions = p
def meetingHasEnded() = meetingEnded = true
def hasMeetingEnded(): Boolean = meetingEnded
def timeNowInMinutes(): Long = TimeUnit.NANOSECONDS.toMinutes(System.nanoTime())
def timeNowInSeconds(): Long = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime())
def getMeetingExtensionProp(): MeetingExtensionProp = extension
def muteMeeting() = meetingMuted = true
def unmuteMeeting() = meetingMuted = false
def isMeetingMuted(): Boolean = meetingMuted
def recordingStarted() = recording = true
def recordingStopped() = recording = false
def isRecording(): Boolean = recording
def lastWebUserLeft() = lastWebUserLeftOnTimestamp = timeNowInMinutes
def lastWebUserLeftOn(): Long = lastWebUserLeftOnTimestamp
def resetLastWebUserLeftOn() = lastWebUserLeftOnTimestamp = 0
def setVoiceRecordingFilename(path: String) = voiceRecordingFilename = path
def getVoiceRecordingFilename(): String = voiceRecordingFilename
def permisionsInitialized(): Boolean = permissionsInited
def initializePermissions() = permissionsInited = true
def audioSettingsInitialized(): Boolean = audioSettingsInited
def initializeAudioSettings() = audioSettingsInited = true
def permissionsEqual(other: Permissions): Boolean = permissions == other
def lockLayout(lock: Boolean) = permissions = permissions.copy(lockedLayout = lock)
def getPermissions(): Permissions = permissions
def setPermissions(p: Permissions) = permissions = p
def meetingHasEnded() = meetingEnded = true
def hasMeetingEnded(): Boolean = meetingEnded
def timeNowInMinutes(): Long = TimeUnit.NANOSECONDS.toMinutes(System.nanoTime())
def timeNowInSeconds(): Long = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime())
def getGuestPolicy(): GuestPolicy.GuestPolicy = guestPolicy
def setGuestPolicy(policy: GuestPolicy.GuestPolicy) = guestPolicy = policy
def getGuestPolicySetBy(): String = guestPolicySetBy
def setGuestPolicySetBy(user: String) = guestPolicySetBy = user
*/
}

View File

@ -1,39 +1,19 @@
package org.bigbluebutton.core
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Resume
import java.io.{ PrintWriter, StringWriter }
import org.bigbluebutton.core.api._
import org.bigbluebutton.common.messages.MessagingConstants
import org.bigbluebutton.core.pubsub.senders.ChatMessageToJsonConverter
import org.bigbluebutton.common.messages.StartRecordingVoiceConfRequestMessage
import org.bigbluebutton.common.messages.StopRecordingVoiceConfRequestMessage
import org.bigbluebutton.core.pubsub.senders.MeetingMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.PesentationMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.CaptionMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.DeskShareMessageToJsonConverter
import org.bigbluebutton.common.messages.GetPresentationInfoReplyMessage
import org.bigbluebutton.common.messages.PresentationRemovedMessage
import org.bigbluebutton.common.messages.AllowUserToShareDesktopReply
import org.bigbluebutton.core.apps.Page
import collection.JavaConverters._
import scala.collection.JavaConversions._
import org.bigbluebutton.core.apps.SimplePollResultOutVO
import org.bigbluebutton.core.apps.SimplePollOutVO
import scala.concurrent.duration._
import org.bigbluebutton.core.pubsub.senders.UsersMessageToJsonConverter
import org.bigbluebutton.common.messages.GetUsersFromVoiceConfRequestMessage
import org.bigbluebutton.common.messages.MuteUserInVoiceConfRequestMessage
import org.bigbluebutton.common.messages.EjectUserFromVoiceConfRequestMessage
import org.bigbluebutton.common.messages.GetCurrentLayoutReplyMessage
import org.bigbluebutton.common.messages.BroadcastLayoutMessage
import org.bigbluebutton.common.messages.UserEjectedFromMeetingMessage
import org.bigbluebutton.common.messages.LockLayoutMessage
import org.bigbluebutton.core.pubsub.senders.WhiteboardMessageToJsonConverter
import org.bigbluebutton.common.converters.ToJsonEncoder
import org.bigbluebutton.common.messages.TransferUserToVoiceConfRequestMessage
import org.bigbluebutton.core
import scala.collection.JavaConverters
object MessageSenderActor {
def props(msgSender: MessageSender): Props =
@ -43,158 +23,35 @@ object MessageSenderActor {
class MessageSenderActor(val service: MessageSender)
extends Actor with ActorLogging {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => {
val sw: StringWriter = new StringWriter()
sw.write("An exception has been thrown on MessageSenderActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n")
e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString())
Resume
}
}
val encoder = new ToJsonEncoder()
def receive = {
case msg: UserEjectedFromMeeting => handleUserEjectedFromMeeting(msg)
case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg)
case msg: SendPublicMessageEvent => handleSendPublicMessageEvent(msg)
case msg: SendPrivateMessageEvent => handleSendPrivateMessageEvent(msg)
case msg: MeetingCreated => handleMeetingCreated(msg)
case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg)
case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg)
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
case msg: MeetingCreated => handleMeetingCreated(msg)
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
case msg: GetRecordingStatusReply => handleGetRecordingStatusReply(msg)
case msg: MeetingEnding => handleMeetingEnding(msg)
case msg: MeetingEnded => handleMeetingEnded(msg)
case msg: MeetingHasEnded => handleMeetingHasEnded(msg)
case msg: MeetingDestroyed => handleMeetingDestroyed(msg)
case msg: KeepAliveMessageReply => handleKeepAliveMessageReply(msg)
case msg: PubSubPong => handlePubSubPong(msg)
case msg: StartRecording => handleStartRecording(msg)
case msg: StopRecording => handleStopRecording(msg)
case msg: GetAllMeetingsReply => handleGetAllMeetingsReply(msg)
case msg: StartRecordingVoiceConf => handleStartRecordingVoiceConf(msg)
case msg: StopRecordingVoiceConf => handleStopRecordingVoiceConf(msg)
case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg)
case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg)
case msg: GetPresentationInfoOutMsg => handleGetPresentationInfoOutMsg(msg)
case msg: SendCursorUpdateOutMsg => handleSendCursorUpdateOutMsg(msg)
case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg)
case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg)
case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg)
case msg: GetSlideInfoOutMsg => handleGetSlideInfoOutMsg(msg)
case msg: PresentationConversionProgress => handlePresentationConversionProgress(msg)
case msg: PresentationConversionError => handlePresentationConversionError(msg)
case msg: PresentationPageGenerated => handlePresentationPageGenerated(msg)
case msg: PresentationConversionDone => handlePresentationConversionDone(msg)
case msg: PollStartedMessage => handlePollStartedMessage(msg)
case msg: PollStoppedMessage => handlePollStoppedMessage(msg)
case msg: PollShowResultMessage => handlePollShowResultMessage(msg)
case msg: PollHideResultMessage => handlePollHideResultMessage(msg)
case msg: UserRespondedToPollMessage => handleUserRespondedToPollMessage(msg)
case msg: MeetingMuted => handleMeetingMuted(msg)
case msg: MeetingState => handleMeetingState(msg)
case msg: DisconnectAllUsers => handleDisconnectAllUsers(msg)
case msg: AllowUserToShareDesktopOut => handleAllowUserToShareDesktopOut(msg)
case msg: DisconnectUser => handleDisconnectUser(msg)
case msg: PermissionsSettingInitialized => handlePermissionsSettingInitialized(msg)
case msg: NewPermissionsSetting => handleNewPermissionsSetting(msg)
case msg: UserLocked => handleUserLocked(msg)
case msg: GetPermissionsSettingReply => handleGetPermissionsSettingReply(msg)
case msg: UserRegistered => handleUserRegistered(msg)
case msg: UserLeft => handleUserLeft(msg)
case msg: PresenterAssigned => handlePresenterAssigned(msg)
case msg: EndAndKickAll => handleEndAndKickAll(msg)
case msg: GetUsersReply => handleGetUsersReply(msg)
case msg: ValidateAuthTokenReply => handleValidateAuthTokenReply(msg)
case msg: ValidateAuthTokenTimedOut => handleValidateAuthTokenTimedOut(msg)
case msg: UserJoined => handleUserJoined(msg)
case msg: UserChangedEmojiStatus => handleChangedUserEmojiStatus(msg)
case msg: UserSharedWebcam => handleUserSharedWebcam(msg)
case msg: UserUnsharedWebcam => handleUserUnsharedWebcam(msg)
case msg: UserStatusChange => handleUserStatusChange(msg)
case msg: UserVoiceMuted => handleUserVoiceMuted(msg)
case msg: UserVoiceTalking => handleUserVoiceTalking(msg)
case msg: MuteVoiceUser => handleMuteVoiceUser(msg)
case msg: EjectVoiceUser => handleEjectVoiceUser(msg)
case msg: TransferUserToMeeting => handleTransferUserToMeeting(msg)
case msg: GetUsersInVoiceConference => handleGetUsersFromVoiceConference(msg)
case msg: UserJoinedVoice => handleUserJoinedVoice(msg)
case msg: UserLeftVoice => handleUserLeftVoice(msg)
case msg: IsMeetingMutedReply => handleIsMeetingMutedReply(msg)
case msg: UserListeningOnly => handleUserListeningOnly(msg)
case msg: GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
case msg: BroadcastLayoutEvent => handleBroadcastLayoutEvent(msg)
case msg: LockLayoutEvent => handleLockLayoutEvent(msg)
case msg: GetWhiteboardShapesReply => handleGetWhiteboardShapesReply(msg)
case msg: SendWhiteboardAnnotationEvent => handleSendWhiteboardAnnotationEvent(msg)
case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg)
case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg)
case msg: WhiteboardEnabledEvent => handleWhiteboardEnabledEvent(msg)
case msg: IsWhiteboardEnabledReply => handleIsWhiteboardEnabledReply(msg)
// breakout room cases
case msg: BreakoutRoomsListOutMessage => handleBreakoutRoomsListOutMessage(msg)
case msg: BreakoutRoomStartedOutMessage => handleBreakoutRoomStartedOutMessage(msg)
case msg: BreakoutRoomEndedOutMessage => handleBreakoutRoomEndedOutMessage(msg)
case msg: BreakoutRoomJoinURLOutMessage => handleBreakoutRoomJoinURLOutMessage(msg)
case msg: UpdateBreakoutUsersOutMessage => handleUpdateBreakoutUsersOutMessage(msg)
case msg: MeetingTimeRemainingUpdate => handleMeetingTimeRemainingUpdate(msg)
case msg: BreakoutRoomsTimeRemainingUpdateOutMessage => handleBreakoutRoomsTimeRemainingUpdate(msg)
case msg: SendCaptionHistoryReply => handleSendCaptionHistoryReply(msg)
case msg: UpdateCaptionOwnerReply => handleUpdateCaptionOwnerReply(msg)
case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg)
case msg: DeskShareStartRTMPBroadcast => handleDeskShareStartRTMPBroadcast(msg)
case msg: DeskShareStopRTMPBroadcast => handleDeskShareStopRTMPBroadcast(msg)
case msg: DeskShareNotifyViewersRTMP => handleDeskShareNotifyViewersRTMP(msg)
case msg: DeskShareNotifyASingleViewer => handleDeskShareNotifyASingleViewer(msg)
case msg: DeskShareHangUp => handleDeskShareHangUp(msg)
case _ => // do nothing
}
private def handleUserEjectedFromMeeting(msg: UserEjectedFromMeeting) {
val m = new UserEjectedFromMeetingMessage(msg.meetingID, msg.userId, msg.ejectedBy)
service.send(MessagingConstants.FROM_USERS_CHANNEL, m.toJson)
}
private def handleDeskShareHangUp(msg: DeskShareHangUp) {
val json = DeskShareMessageToJsonConverter.getDeskShareHangUpToJson(msg)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, json)
}
private def handleDeskShareStopRTMPBroadcast(msg: DeskShareStopRTMPBroadcast) {
val json = DeskShareMessageToJsonConverter.getDeskShareStopRTMPBroadcastToJson(msg)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, json)
}
private def handleDeskShareNotifyViewersRTMP(msg: DeskShareNotifyViewersRTMP) {
val json = DeskShareMessageToJsonConverter.getDeskShareNotifyViewersRTMPToJson(msg)
service.send(MessagingConstants.FROM_DESK_SHARE_CHANNEL, json)
}
def handleDeskShareNotifyASingleViewer(msg: DeskShareNotifyASingleViewer) {
val json = DeskShareMessageToJsonConverter.getDeskShareNotifyASingleViewerToJson(msg)
service.send(MessagingConstants.FROM_DESK_SHARE_CHANNEL, json)
}
private def handleDeskShareStartRTMPBroadcast(msg: DeskShareStartRTMPBroadcast) {
val json = DeskShareMessageToJsonConverter.getDeskShareStartRTMPBroadcastToJson(msg)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, json)
}
private def handleGetChatHistoryReply(msg: GetChatHistoryReply) {
val json = ChatMessageToJsonConverter.getChatHistoryReplyToJson(msg)
service.send(MessagingConstants.FROM_CHAT_CHANNEL, json)
}
private def handleSendPublicMessageEvent(msg: SendPublicMessageEvent) {
val json = ChatMessageToJsonConverter.sendPublicMessageEventToJson(msg)
service.send(MessagingConstants.FROM_CHAT_CHANNEL, json)
}
private def handleSendPrivateMessageEvent(msg: SendPrivateMessageEvent) {
val json = ChatMessageToJsonConverter.sendPrivateMessageEventToJson(msg)
service.send(MessagingConstants.FROM_CHAT_CHANNEL, json)
}
private def handleStartRecordingVoiceConf(msg: StartRecordingVoiceConf) {
val m = new StartRecordingVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleStopRecordingVoiceConf(msg: StopRecordingVoiceConf) {
val m = new StopRecordingVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId, msg.recordedStream)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
case msg: MeetingEnding => handleMeetingEnding(msg)
case msg: MeetingEnded => handleMeetingEnded(msg)
case msg: MeetingHasEnded => handleMeetingHasEnded(msg)
case msg: MeetingDestroyed => handleMeetingDestroyed(msg)
case msg: KeepAliveMessageReply => handleKeepAliveMessageReply(msg)
case msg: PubSubPong => handlePubSubPong(msg)
case msg: InactivityWarning => handleInactivityWarning(msg)
case msg: MeetingIsActive => handleMeetingIsActive(msg)
case msg: GetAllMeetingsReply => handleGetAllMeetingsReply(msg)
case msg: MeetingMuted => handleMeetingMuted(msg)
case msg: MeetingState => handleMeetingState(msg)
case msg: DisconnectAllUsers => handleDisconnectAllUsers(msg)
case msg: DisconnectUser => handleDisconnectUser(msg)
case _ => // do nothing
}
private def handleMeetingDestroyed(msg: MeetingDestroyed) {
@ -230,26 +87,6 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleStartRecording(msg: StartRecording) {
val json = MeetingMessageToJsonConverter.startRecordingToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleStopRecording(msg: StopRecording) {
val json = MeetingMessageToJsonConverter.stopRecordingToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleVoiceRecordingStarted(msg: VoiceRecordingStarted) {
val json = MeetingMessageToJsonConverter.voiceRecordingStartedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleVoiceRecordingStopped(msg: VoiceRecordingStopped) {
val json = MeetingMessageToJsonConverter.voiceRecordingStoppedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleRecordingStatusChanged(msg: RecordingStatusChanged) {
val json = MeetingMessageToJsonConverter.recordingStatusChangedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
@ -279,249 +116,14 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def pageToMap(page: Page): java.util.Map[String, Any] = {
val res = new scala.collection.mutable.HashMap[String, Any]
res += "id" -> page.id
res += "num" -> page.num
res += "thumb_uri" -> page.thumbUri
res += "swf_uri" -> page.swfUri
res += "txt_uri" -> page.txtUri
res += "svg_uri" -> page.svgUri
res += "current" -> page.current
res += "x_offset" -> page.xOffset
res += "y_offset" -> page.yOffset
res += "width_ratio" -> page.widthRatio
res += "height_ratio" -> page.heightRatio
mapAsJavaMap(res)
private def handleInactivityWarning(msg: InactivityWarning) {
val json = MeetingMessageToJsonConverter.inactivityWarningToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleClearPresentationOutMsg(msg: ClearPresentationOutMsg) {
val json = PesentationMessageToJsonConverter.clearPresentationOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleRemovePresentationOutMsg(msg: RemovePresentationOutMsg) {
val m = new PresentationRemovedMessage(msg.meetingID, msg.presentationID)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, m.toJson())
}
private def handleGetPresentationInfoOutMsg(msg: GetPresentationInfoOutMsg) {
// Create a map for our current presenter
val presenter = new java.util.HashMap[String, Object]()
presenter.put(Constants.USER_ID, msg.info.presenter.userId)
presenter.put(Constants.NAME, msg.info.presenter.name)
presenter.put(Constants.ASSIGNED_BY, msg.info.presenter.assignedBy)
// Create an array for our presentations
val presentations = new java.util.ArrayList[java.util.Map[String, Object]]
msg.info.presentations.foreach { pres =>
val presentation = new java.util.HashMap[String, Object]()
presentation.put(Constants.ID, pres.id)
presentation.put(Constants.NAME, pres.name)
presentation.put(Constants.CURRENT, pres.current: java.lang.Boolean)
// Get the pages for a presentation
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
pres.pages.values foreach { p =>
pages.add(pageToMap(p))
}
// store the pages in the presentation
presentation.put(Constants.PAGES, pages)
// add this presentation into our presentations list
presentations.add(presentation);
}
val reply = new GetPresentationInfoReplyMessage(msg.meetingID, msg.requesterID, presenter, presentations)
val json = PesentationMessageToJsonConverter.getPresentationInfoOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleSendCursorUpdateOutMsg(msg: SendCursorUpdateOutMsg) {
val json = PesentationMessageToJsonConverter.sendCursorUpdateOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleResizeAndMoveSlideOutMsg(msg: ResizeAndMoveSlideOutMsg) {
val json = PesentationMessageToJsonConverter.resizeAndMoveSlideOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGotoSlideOutMsg(msg: GotoSlideOutMsg) {
val json = PesentationMessageToJsonConverter.gotoSlideOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleSharePresentationOutMsg(msg: SharePresentationOutMsg) {
val json = PesentationMessageToJsonConverter.sharePresentationOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGetSlideInfoOutMsg(msg: GetSlideInfoOutMsg) {
val json = PesentationMessageToJsonConverter.getSlideInfoOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGetPreuploadedPresentationsOutMsg(msg: GetPreuploadedPresentationsOutMsg) {
val json = PesentationMessageToJsonConverter.getPreuploadedPresentationsOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationConversionProgress(msg: PresentationConversionProgress) {
val json = PesentationMessageToJsonConverter.presentationConversionProgressToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationConversionError(msg: PresentationConversionError) {
val json = PesentationMessageToJsonConverter.presentationConversionErrorToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationPageGenerated(msg: PresentationPageGenerated) {
val json = PesentationMessageToJsonConverter.presentationPageGenerated(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationConversionDone(msg: PresentationConversionDone) {
val json = PesentationMessageToJsonConverter.presentationConversionDoneToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationChanged(msg: PresentationChanged) {
val json = PesentationMessageToJsonConverter.presentationChangedToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleGetPresentationStatusReply(msg: GetPresentationStatusReply) {
val json = PesentationMessageToJsonConverter.getPresentationStatusReplyToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePresentationRemoved(msg: PresentationRemoved) {
val json = PesentationMessageToJsonConverter.presentationRemovedToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePageChanged(msg: PageChanged) {
val json = PesentationMessageToJsonConverter.pageChangedToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handlePollStartedMessage(msg: PollStartedMessage) {
val json = pollStartedMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollStoppedMessage(msg: PollStoppedMessage) {
val json = pollStoppedMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollShowResultMessage(msg: PollShowResultMessage) {
val json = pollShowResultMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollHideResultMessage(msg: PollHideResultMessage) {
val json = pollHideResultMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handleUserRespondedToPollMessage(msg: UserRespondedToPollMessage) {
val json = UserRespondedToPollMessageTpJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def pollVOtoMap(msg: SimplePollOutVO): java.util.HashMap[String, Object] = {
val pollVO = new java.util.HashMap[String, Object]()
pollVO.put("id", msg.id)
val answers = new java.util.ArrayList[java.util.Map[String, Any]];
msg.answers.foreach(ans => {
val amap = new java.util.HashMap[String, Any]()
amap.put("id", ans.id)
amap.put("key", ans.key)
answers.add(amap)
})
pollVO.put("answers", answers)
pollVO
}
private def pollStartedMessageToJson(msg: PollStartedMessage): String = {
val pollVO = pollVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.PollStartedMessage(msg.meetingID, msg.requesterId, pollVO)
psm.toJson
}
private def pollStoppedMessageToJson(msg: PollStoppedMessage): String = {
val psm = new org.bigbluebutton.common.messages.PollStoppedMessage(msg.meetingID, msg.requesterId, msg.pollId)
psm.toJson
}
private def pollResultVOtoMap(msg: SimplePollResultOutVO): java.util.HashMap[String, Object] = {
val pollVO = new java.util.HashMap[String, Object]()
pollVO.put("id", msg.id)
pollVO.put("num_respondents", msg.numRespondents: java.lang.Integer)
pollVO.put("num_responders", msg.numResponders: java.lang.Integer)
val answers = new java.util.ArrayList[java.util.Map[String, Any]];
msg.answers.foreach(ans => {
val amap = new java.util.HashMap[String, Any]()
amap.put("id", ans.id)
amap.put("key", ans.key)
amap.put("num_votes", ans.numVotes)
answers.add(amap)
})
pollVO.put("answers", answers)
pollVO
}
private def pollShowResultMessageToJson(msg: PollShowResultMessage): String = {
val pollResultVO = pollResultVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.PollShowResultMessage(msg.meetingID, pollResultVO)
psm.toJson
}
private def pollHideResultMessageToJson(msg: PollHideResultMessage): String = {
val psm = new org.bigbluebutton.common.messages.PollHideResultMessage(msg.meetingID, msg.pollId)
psm.toJson
}
private def UserRespondedToPollMessageTpJson(msg: UserRespondedToPollMessage): String = {
val pollResultVO = pollResultVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.UserVotedPollMessage(msg.meetingID, msg.presenterId, pollResultVO)
psm.toJson
}
private def handleLockLayoutEvent(msg: LockLayoutEvent) {
val users = new java.util.ArrayList[String];
msg.applyTo.foreach(uvo => {
users.add(uvo.userID)
})
val evt = new LockLayoutMessage(msg.meetingID, msg.setById, msg.locked, users)
service.send(MessagingConstants.FROM_USERS_CHANNEL, evt.toJson())
}
private def handleBroadcastLayoutEvent(msg: BroadcastLayoutEvent) {
val users = new java.util.ArrayList[String];
msg.applyTo.foreach(uvo => {
users.add(uvo.userID)
})
val evt = new BroadcastLayoutMessage(msg.meetingID, msg.setByUserID, msg.layoutID, msg.locked, users)
service.send(MessagingConstants.FROM_USERS_CHANNEL, evt.toJson())
}
private def handleGetCurrentLayoutReply(msg: GetCurrentLayoutReply) {
val reply = new GetCurrentLayoutReplyMessage(msg.meetingID, msg.requesterID, msg.setByUserID, msg.layoutID, msg.locked)
service.send(MessagingConstants.FROM_USERS_CHANNEL, reply.toJson())
private def handleMeetingIsActive(msg: MeetingIsActive) {
val json = MeetingMessageToJsonConverter.meetingIsActiveToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleMeetingState(msg: MeetingState) {
@ -543,233 +145,4 @@ class MessageSenderActor(val service: MessageSender)
val json = UsersMessageToJsonConverter.disconnectUserToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleAllowUserToShareDesktopOut(msg: AllowUserToShareDesktopOut): Unit = {
val obj = new AllowUserToShareDesktopReply(msg.meetingID, msg.userID, msg.allowed,
TimestampGenerator.generateTimestamp)
val json = obj.toJson()
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handlePermissionsSettingInitialized(msg: PermissionsSettingInitialized) {
val json = UsersMessageToJsonConverter.permissionsSettingInitializedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleNewPermissionsSetting(msg: NewPermissionsSetting) {
val json = UsersMessageToJsonConverter.newPermissionsSettingToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleUserLocked(msg: UserLocked) {
val json = UsersMessageToJsonConverter.userLockedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleGetPermissionsSettingReply(msg: GetPermissionsSettingReply) {
val json = UsersMessageToJsonConverter.getPermissionsSettingReplyToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleUserRegistered(msg: UserRegistered) {
val json = UsersMessageToJsonConverter.userRegisteredToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
handleRegisteredUser(msg);
}
private def handleUserStatusChange(msg: UserStatusChange) {
val json = UsersMessageToJsonConverter.userStatusChangeToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleChangedUserEmojiStatus(msg: UserChangedEmojiStatus) {
val json = UsersMessageToJsonConverter.userChangedEmojiStatusToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserSharedWebcam(msg: UserSharedWebcam) {
val json = UsersMessageToJsonConverter.userSharedWebcamToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserUnsharedWebcam(msg: UserUnsharedWebcam) {
val json = UsersMessageToJsonConverter.userUnsharedWebcamToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleGetUsersReply(msg: GetUsersReply) {
val json = UsersMessageToJsonConverter.getUsersReplyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserJoinedVoice(msg: UserJoinedVoice) {
val json = UsersMessageToJsonConverter.userJoinedVoice(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserVoiceMuted(msg: UserVoiceMuted) {
val json = UsersMessageToJsonConverter.userVoiceMuted(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserVoiceTalking(msg: UserVoiceTalking) {
val json = UsersMessageToJsonConverter.userVoiceTalking(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleMuteVoiceUser(msg: MuteVoiceUser) {
val m = new MuteUserInVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId, msg.voiceUserId, msg.mute)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleGetUsersFromVoiceConference(msg: GetUsersInVoiceConference) {
val m = new GetUsersFromVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleEjectVoiceUser(msg: EjectVoiceUser) {
val m = new EjectUserFromVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId, msg.voiceUserId)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleTransferUserToMeeting(msg: TransferUserToMeeting) {
val m = new TransferUserToVoiceConfRequestMessage(msg.voiceConfId, msg.targetVoiceConfId, msg.userId);
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())
}
private def handleUserLeftVoice(msg: UserLeftVoice) {
val json = UsersMessageToJsonConverter.userLeftVoiceToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleIsMeetingMutedReply(msg: IsMeetingMutedReply) {
val json = UsersMessageToJsonConverter.isMeetingMutedReplyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleValidateAuthTokenReply(msg: ValidateAuthTokenReply) {
println("**** handleValidateAuthTokenReply *****")
val json = UsersMessageToJsonConverter.validateAuthTokenReplyToJson(msg)
//println("************** Publishing [" + json + "] *******************")
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleValidateAuthTokenTimedOut(msg: ValidateAuthTokenTimedOut) {
println("**** handleValidateAuthTokenTimedOut *****")
val json = UsersMessageToJsonConverter.validateAuthTokenTimeoutToJson(msg)
//println("************** Publishing [" + json + "] *******************")
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserJoined(msg: UserJoined) {
val json = UsersMessageToJsonConverter.userJoinedToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleRegisteredUser(msg: UserRegistered) {
val json = UsersMessageToJsonConverter.userRegisteredToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserLeft(msg: UserLeft) {
val json = UsersMessageToJsonConverter.userLeftToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handlePresenterAssigned(msg: PresenterAssigned) {
val json = UsersMessageToJsonConverter.presenterAssignedToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleEndAndKickAll(msg: EndAndKickAll) {
val json = UsersMessageToJsonConverter.endAndKickAllToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUserListeningOnly(msg: UserListeningOnly) {
val json = UsersMessageToJsonConverter.userListeningOnlyToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleGetWhiteboardShapesReply(msg: GetWhiteboardShapesReply) {
val json = WhiteboardMessageToJsonConverter.getWhiteboardShapesReplyToJson(msg)
service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
}
private def handleSendWhiteboardAnnotationEvent(msg: SendWhiteboardAnnotationEvent) {
val json = WhiteboardMessageToJsonConverter.sendWhiteboardAnnotationEventToJson(msg)
service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
}
private def handleClearWhiteboardEvent(msg: ClearWhiteboardEvent) {
val json = WhiteboardMessageToJsonConverter.clearWhiteboardEventToJson(msg)
service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
}
private def handleUndoWhiteboardEvent(msg: UndoWhiteboardEvent) {
val json = WhiteboardMessageToJsonConverter.undoWhiteboardEventToJson(msg)
service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
}
private def handleWhiteboardEnabledEvent(msg: WhiteboardEnabledEvent) {
val json = WhiteboardMessageToJsonConverter.whiteboardEnabledEventToJson(msg)
service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
}
private def handleIsWhiteboardEnabledReply(msg: IsWhiteboardEnabledReply) {
val json = WhiteboardMessageToJsonConverter.isWhiteboardEnabledReplyToJson(msg)
service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json)
}
private def handleBreakoutRoomsListOutMessage(msg: BreakoutRoomsListOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomsListOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomStartedOutMessage(msg: BreakoutRoomStartedOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomStartedOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomEndedOutMessage(msg: BreakoutRoomEndedOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomEndedOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleBreakoutRoomJoinURLOutMessage(msg: BreakoutRoomJoinURLOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomJoinURLOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleUpdateBreakoutUsersOutMessage(msg: UpdateBreakoutUsersOutMessage) {
val json = MeetingMessageToJsonConverter.updateBreakoutUsersOutMessageToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleMeetingTimeRemainingUpdate(msg: MeetingTimeRemainingUpdate) {
val json = MeetingMessageToJsonConverter.meetingTimeRemainingUpdateToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
private def handleSendCaptionHistoryReply(msg: SendCaptionHistoryReply) {
val json = CaptionMessageToJsonConverter.sendCaptionHistoryReplyToJson(msg)
service.send(MessagingConstants.FROM_CAPTION_CHANNEL, json)
}
private def handleUpdateCaptionOwnerReply(msg: UpdateCaptionOwnerReply) {
val json = CaptionMessageToJsonConverter.updateCaptionOwnerReplyToJson(msg)
service.send(MessagingConstants.FROM_CAPTION_CHANNEL, json)
}
private def handleEditCaptionHistoryReply(msg: EditCaptionHistoryReply) {
println("handleEditCaptionHistoryReply")
val json = CaptionMessageToJsonConverter.editCaptionHistoryReplyToJson(msg)
println(json)
service.send(MessagingConstants.FROM_CAPTION_CHANNEL, json)
}
private def handleBreakoutRoomsTimeRemainingUpdate(msg: BreakoutRoomsTimeRemainingUpdateOutMessage) {
val json = MeetingMessageToJsonConverter.breakoutRoomsTimeRemainingUpdateToJson(msg)
service.send(MessagingConstants.FROM_USERS_CHANNEL, json)
}
}

View File

@ -1,19 +1,10 @@
package org.bigbluebutton.core
import akka.actor.ActorRef
import akka.actor.ActorContext
import org.bigbluebutton.core.bus.OutgoingEventBus
import org.bigbluebutton.core.bus.BigBlueButtonOutMessage
import org.bigbluebutton.core.api.IOutMessage
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg }
object OutMessageGateway {
def apply(outgoingEventBus: OutgoingEventBus) =
new OutMessageGateway(outgoingEventBus)
trait OutMessageGateway {
def send(msg: BbbCommonEnvCoreMsg): Unit
def record(msg: BbbCommonEnvCoreMsg): Unit
}
class OutMessageGateway(outgoingEventBus: OutgoingEventBus) {
def send(msg: IOutMessage) {
outgoingEventBus.publish(BigBlueButtonOutMessage("outgoingMessageChannel", msg))
}
}

View File

@ -1,35 +1,39 @@
package org.bigbluebutton.core
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Resume
import java.io.{ PrintWriter, StringWriter }
import org.bigbluebutton.core.api._
import java.util.concurrent.TimeUnit
import org.bigbluebutton.core.util._
import scala.concurrent.duration._
import org.bigbluebutton.core.apps.{ PollApp, UsersApp, PresentationApp, LayoutApp, ChatApp, WhiteboardApp, CaptionApp }
import org.bigbluebutton.core.apps.{ ChatModel, LayoutModel, UsersModel, PollModel, WhiteboardModel, CaptionModel }
import org.bigbluebutton.core.apps.PresentationModel
import org.bigbluebutton.core.service.recorder.RecorderApplication
object OutMessageGatewayActor {
def props(meetingId: String, recorder: RecorderApplication, sender: MessageSender): Props =
Props(classOf[OutMessageGatewayActor], meetingId, recorder, sender)
def props(meetingId: String, sender: MessageSender): Props =
Props(classOf[OutMessageGatewayActor], meetingId, sender)
}
class OutMessageGatewayActor(val meetingId: String, val recorder: RecorderApplication, val msgSender: MessageSender)
class OutMessageGatewayActor(val meetingId: String, val msgSender: MessageSender)
extends Actor with ActorLogging {
private val recorderActor = context.actorOf(RecorderActor.props(recorder), "recorderActor-" + meetingId)
private val msgSenderActor = context.actorOf(MessageSenderActor.props(msgSender), "senderActor-" + meetingId)
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => {
val sw: StringWriter = new StringWriter()
sw.write("An exception has been thrown on OutMessageGatewayActor, exception message [" + e.getMessage() + "] (full stacktrace below)\n")
e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString())
Resume
}
}
def receive = {
case msg: IOutMessage => {
msgSenderActor forward msg
recorderActor forward msg
}
case _ => // do nothing
}
}
}

View File

@ -0,0 +1,27 @@
package org.bigbluebutton.core
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreMsg }
import org.bigbluebutton.core.api.IOutMessage
import org.bigbluebutton.core.bus._
object OutMessageGatewayImp {
def apply(
outBus2: OutEventBus2
) =
new OutMessageGatewayImp(outBus2)
}
class OutMessageGatewayImp(
outBus2: OutEventBus2
) extends OutMessageGateway
with SystemConfiguration {
def send(msg: BbbCommonEnvCoreMsg): Unit = {
outBus2.publish(BbbOutMessage(outBbbMsgMsgChannel, msg))
}
def record(msg: BbbCommonEnvCoreMsg): Unit = {
outBus2.publish(BbbOutMessage(recordServiceMessageChannel, msg))
}
}

View File

@ -1,39 +0,0 @@
package org.bigbluebutton.core
import spray.json.{ DefaultJsonProtocol, JsValue, JsString, DeserializationException, JsonFormat }
import org.bigbluebutton.core.api._
object UserMessagesProtocol extends DefaultJsonProtocol {
/*
implicit object RoleJsonFormat extends JsonFormat[Role.RoleType] {
def write(obj: Role.RoleType): JsValue = JsString(obj.toString)
def read(json: JsValue): Role.RoleType = json match {
case JsString(str) => Role.withName(str)
case _ => throw new DeserializationException("Enum string expected")
}
}
*/
implicit object MessageTypeFormat extends JsonFormat[MessageType.MessageType] {
def write(obj: MessageType.MessageType): JsValue = JsString(obj.toString)
def read(json: JsValue): MessageType.MessageType = json match {
case JsString(str) => MessageType.withName(str)
case _ => throw new DeserializationException("Enum string expected")
}
}
implicit val breakoutRoomInPayloadFormat = jsonFormat3(BreakoutRoomInPayload)
implicit val createBreakoutRoomsFormat = jsonFormat4(CreateBreakoutRooms)
implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage)
implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat3(RequestBreakoutJoinURLInMessage)
implicit val transferUserToMeetingRequestFormat = jsonFormat3(TransferUserToMeetingRequest)
implicit val endBreakoutRoomsFormat = jsonFormat1(EndAllBreakoutRooms)
implicit val inMsgHeaderFormat = jsonFormat1(InMessageHeader)
implicit val outMsgHeaderFormat = jsonFormat1(OutMsgHeader)
implicit val outMsgEnvelopeHeaderFormat = jsonFormat2(OutMsgEnvelopeHeader)
implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat11(CreateBreakoutRoomOutMsgPayload)
implicit val createBreakoutRoomOutMsgEnvelopePayloadFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelopePayload)
implicit val createBreakoutRoomOutMsgEnvelopeFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelope)
}

View File

@ -1,13 +0,0 @@
package org.bigbluebutton.core
case class OutMsgHeader(name: String)
case class OutMsgEnvelopeHeader(`type`: MessageType.MessageType, address: String)
trait OutMessage
case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, payload: CreateBreakoutRoomOutMsgEnvelopePayload)
case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, payload: CreateBreakoutRoomOutMsgPayload)
case class CreateBreakoutRoomOutMsgPayload(meetingId: String, parentId: String, name: String,
voiceConfId: String, moderatorPassword: String, viewerPassword: String,
durationInMinutes: Int, sourcePresentationId: String, sourcePresentationSlide: Int,
record: Boolean, sequence: Int)

View File

@ -1,491 +0,0 @@
package org.bigbluebutton.core
import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.ActorLogging
import akka.actor.Props
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.api._
import scala.collection.JavaConversions._
import org.bigbluebutton.core.service.recorder.RecorderApplication
import org.bigbluebutton.core.recorders.events.PublicChatRecordEvent
import org.bigbluebutton.core.recorders.events.ConversionCompletedPresentationRecordEvent
import org.bigbluebutton.core.recorders.events.GotoSlidePresentationRecordEvent
import org.bigbluebutton.core.recorders.events.ResizeAndMoveSlidePresentationRecordEvent
import org.bigbluebutton.core.recorders.events.RemovePresentationPresentationRecordEvent
import org.bigbluebutton.core.recorders.events.SharePresentationPresentationRecordEvent
import org.bigbluebutton.core.recorders.events.CursorUpdateRecordEvent
import org.bigbluebutton.core.recorders.events.AssignPresenterRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantStatusChangeRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantLeftRecordEvent
import org.bigbluebutton.core.recorders.events.RecordStatusRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantLeftVoiceRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantJoinedVoiceRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantTalkingVoiceRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantMutedVoiceRecordEvent
import org.bigbluebutton.core.recorders.events.StartRecordingVoiceRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantJoinRecordEvent
import org.bigbluebutton.core.recorders.events.ParticipantEndAndKickAllRecordEvent
import org.bigbluebutton.core.recorders.events.UndoShapeWhiteboardRecordEvent
import org.bigbluebutton.core.recorders.events.ClearPageWhiteboardRecordEvent
import org.bigbluebutton.core.recorders.events.AddShapeWhiteboardRecordEvent
import org.bigbluebutton.core.recorders.events.DeskShareStartRTMPRecordEvent
import org.bigbluebutton.core.recorders.events.DeskShareStopRTMPRecordEvent
import org.bigbluebutton.core.recorders.events.DeskShareNotifyViewersRTMPRecordEvent
// import org.bigbluebutton.core.service.whiteboard.WhiteboardKeyUtil
import org.bigbluebutton.common.messages.WhiteboardKeyUtil
import org.bigbluebutton.core.recorders.events.ModifyTextWhiteboardRecordEvent
import org.bigbluebutton.core.recorders.events.EditCaptionHistoryRecordEvent
import scala.collection.immutable.StringOps
object RecorderActor {
def props(recorder: RecorderApplication): Props =
Props(classOf[RecorderActor], recorder)
}
class RecorderActor(val recorder: RecorderApplication)
extends Actor with ActorLogging {
def receive = {
case msg: SendPublicMessageEvent => handleSendPublicMessageEvent(msg)
case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg)
case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg)
case msg: SendCursorUpdateOutMsg => handleSendCursorUpdateOutMsg(msg)
case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg)
case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg)
case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg)
case msg: EndAndKickAll => handleEndAndKickAll(msg)
case msg: PresenterAssigned => handleAssignPresenter(msg)
case msg: UserJoined => handleUserJoined(msg)
case msg: UserLeft => handleUserLeft(msg)
case msg: UserStatusChange => handleUserStatusChange(msg)
case msg: UserVoiceMuted => handleUserVoiceMuted(msg)
case msg: UserVoiceTalking => handleUserVoiceTalking(msg)
case msg: UserJoinedVoice => handleUserJoinedVoice(msg)
case msg: UserLeftVoice => handleUserLeftVoice(msg)
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
case msg: UserChangedEmojiStatus => handleChangedUserEmojiStatus(msg)
case msg: UserSharedWebcam => handleUserSharedWebcam(msg)
case msg: UserUnsharedWebcam => handleUserUnsharedWebcam(msg)
case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg)
case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg)
case msg: SendWhiteboardAnnotationEvent => handleSendWhiteboardAnnotationEvent(msg)
case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg)
case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg)
case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg)
case msg: DeskShareStartRTMPBroadcast => handleDeskShareStartRTMPBroadcast(msg)
case msg: DeskShareStopRTMPBroadcast => handleDeskShareStopRTMPBroadcast(msg)
case msg: DeskShareNotifyViewersRTMP => handleDeskShareNotifyViewersRTMP(msg)
case _ => // do nothing
}
private def handleSendPublicMessageEvent(msg: SendPublicMessageEvent) {
if (msg.recorded) {
val message = mapAsJavaMap(msg.message)
val ev = new PublicChatRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setMeetingId(msg.meetingID);
ev.setSender(message.get("fromUsername"));
ev.setSenderId(message.get("fromUserID"));
ev.setMessage(message.get("message"));
ev.setColor(message.get("fromColor"));
recorder.record(msg.meetingID, ev);
}
}
private def handleClearPresentationOutMsg(msg: ClearPresentationOutMsg) {
}
private def handlePresentationConversionDone(msg: PresentationConversionDone) {
if (msg.recorded) {
val event = new ConversionCompletedPresentationRecordEvent();
event.setMeetingId(msg.meetingID);
event.setTimestamp(TimestampGenerator.generateTimestamp);
event.setPresentationName(msg.presentation.id);
event.setOriginalFilename(msg.presentation.name);
recorder.record(msg.meetingID, event);
}
}
private def handleGotoSlideOutMsg(msg: GotoSlideOutMsg) {
if (msg.recorded) {
val event = new GotoSlidePresentationRecordEvent();
event.setMeetingId(msg.meetingID);
event.setTimestamp(TimestampGenerator.generateTimestamp);
event.setSlide(msg.page.num);
event.setId(msg.page.id);
event.setNum(msg.page.num);
event.setThumbUri(msg.page.thumbUri);
event.setSwfUri(msg.page.swfUri);
event.setTxtUri(msg.page.txtUri);
event.setSvgUri(msg.page.svgUri);
event.setXOffset(msg.page.xOffset);
event.setYOffset(msg.page.yOffset);
event.setWidthRatio(msg.page.widthRatio);
event.setHeightRatio(msg.page.heightRatio);
recorder.record(msg.meetingID, event);
}
}
private def handleResizeAndMoveSlideOutMsg(msg: ResizeAndMoveSlideOutMsg) {
if (msg.recorded) {
val event = new ResizeAndMoveSlidePresentationRecordEvent();
event.setMeetingId(msg.meetingID);
event.setTimestamp(TimestampGenerator.generateTimestamp);
event.setId(msg.page.id);
event.setNum(msg.page.num);
event.setThumbUri(msg.page.thumbUri);
event.setSwfUri(msg.page.swfUri);
event.setTxtUri(msg.page.txtUri);
event.setSvgUri(msg.page.svgUri);
event.setXOffset(msg.page.xOffset);
event.setYOffset(msg.page.yOffset);
event.setWidthRatio(msg.page.widthRatio);
event.setHeightRatio(msg.page.heightRatio);
recorder.record(msg.meetingID, event);
}
}
private def handleRemovePresentationOutMsg(msg: RemovePresentationOutMsg) {
if (msg.recorded) {
val event = new RemovePresentationPresentationRecordEvent();
event.setMeetingId(msg.meetingID);
event.setTimestamp(TimestampGenerator.generateTimestamp);
event.setPresentationName(msg.presentationID);
recorder.record(msg.meetingID, event);
}
}
private def handleSharePresentationOutMsg(msg: SharePresentationOutMsg) {
if (msg.recorded) {
val event = new SharePresentationPresentationRecordEvent();
event.setMeetingId(msg.meetingID);
event.setTimestamp(TimestampGenerator.generateTimestamp);
event.setPresentationName(msg.presentation.id);
event.setOriginalFilename(msg.presentation.name);
event.setShare(true);
recorder.record(msg.meetingID, event);
}
}
private def handleSendCursorUpdateOutMsg(msg: SendCursorUpdateOutMsg) {
if (msg.recorded) {
val event = new CursorUpdateRecordEvent();
event.setMeetingId(msg.meetingID);
event.setTimestamp(TimestampGenerator.generateTimestamp);
event.setXPercent(msg.xPercent);
event.setYPercent(msg.yPercent);
recorder.record(msg.meetingID, event);
}
}
private def handleEndAndKickAll(msg: EndAndKickAll): Unit = {
if (msg.recorded) {
val ev = new ParticipantEndAndKickAllRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setMeetingId(msg.meetingID);
recorder.record(msg.meetingID, ev);
}
}
private def handleUserJoined(msg: UserJoined): Unit = {
if (msg.recorded) {
val ev = new ParticipantJoinRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setUserId(msg.user.userID);
ev.setExternalUserId(msg.user.externUserID);
ev.setName(msg.user.name);
ev.setMeetingId(msg.meetingID);
ev.setRole(msg.user.role.toString());
recorder.record(msg.meetingID, ev);
}
}
def handleVoiceRecordingStarted(msg: VoiceRecordingStarted) {
if (msg.recorded) {
val evt = new StartRecordingVoiceRecordEvent(true);
evt.setMeetingId(msg.meetingID);
evt.setTimestamp(TimestampGenerator.generateTimestamp);
evt.setBridge(msg.confNum);
evt.setRecordingTimestamp(msg.timestamp);
evt.setFilename(msg.recordingFile);
recorder.record(msg.meetingID, evt);
}
}
def handleVoiceRecordingStopped(msg: VoiceRecordingStopped) {
if (msg.recorded) {
val evt = new StartRecordingVoiceRecordEvent(false);
evt.setMeetingId(msg.meetingID);
evt.setTimestamp(TimestampGenerator.generateTimestamp);
evt.setBridge(msg.confNum);
evt.setRecordingTimestamp(msg.timestamp);
evt.setFilename(msg.recordingFile);
recorder.record(msg.meetingID, evt);
}
}
def handleUserVoiceMuted(msg: UserVoiceMuted) {
if (msg.recorded) {
val ev = new ParticipantMutedVoiceRecordEvent()
ev.setMeetingId(msg.meetingID);
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setBridge(msg.confNum);
ev.setParticipant(msg.user.voiceUser.userId);
ev.setMuted(msg.user.voiceUser.muted);
recorder.record(msg.meetingID, ev);
}
}
def handleUserVoiceTalking(msg: UserVoiceTalking) {
if (msg.recorded) {
val evt = new ParticipantTalkingVoiceRecordEvent();
evt.setMeetingId(msg.meetingID);
evt.setTimestamp(TimestampGenerator.generateTimestamp);
evt.setBridge(msg.confNum);
evt.setParticipant(msg.user.userID);
evt.setTalking(msg.user.voiceUser.talking);
recorder.record(msg.meetingID, evt);
}
}
def handleUserJoinedVoice(msg: UserJoinedVoice) {
if (msg.recorded) {
val evt = new ParticipantJoinedVoiceRecordEvent();
evt.setMeetingId(msg.meetingID);
evt.setTimestamp(TimestampGenerator.generateTimestamp);
evt.setBridge(msg.confNum);
evt.setParticipant(msg.user.voiceUser.userId);
evt.setCallerName(msg.user.voiceUser.callerName);
evt.setCallerNumber(msg.user.voiceUser.callerNum);
evt.setMuted(msg.user.voiceUser.muted);
evt.setTalking(msg.user.voiceUser.talking);
recorder.record(msg.meetingID, evt)
}
}
def handleUserLeftVoice(msg: UserLeftVoice) {
if (msg.recorded) {
val evt = new ParticipantLeftVoiceRecordEvent();
evt.setMeetingId(msg.meetingID);
evt.setTimestamp(TimestampGenerator.generateTimestamp);
evt.setBridge(msg.confNum);
evt.setParticipant(msg.user.voiceUser.userId);
recorder.record(msg.meetingID, evt);
}
}
def handleRecordingStatusChanged(msg: RecordingStatusChanged) {
if (msg.recorded) {
val evt = new RecordStatusRecordEvent();
evt.setMeetingId(msg.meetingID);
evt.setTimestamp(TimestampGenerator.generateTimestamp);
evt.setUserId(msg.userId);
evt.setRecordingStatus(msg.recording.toString);
recorder.record(msg.meetingID, evt);
}
}
private def handleUserLeft(msg: UserLeft): Unit = {
if (msg.recorded) {
val ev = new ParticipantLeftRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setUserId(msg.user.userID);
ev.setMeetingId(msg.meetingID);
recorder.record(msg.meetingID, ev);
}
}
private def handleChangedUserEmojiStatus(msg: UserChangedEmojiStatus) {
if (msg.recorded) {
val status = UserStatusChange(msg.meetingID, msg.recorded,
msg.userID, "emojiStatus", msg.emojiStatus)
handleUserStatusChange(status)
}
}
private def handleUserSharedWebcam(msg: UserSharedWebcam) {
if (msg.recorded) {
val status = UserStatusChange(msg.meetingID, msg.recorded,
msg.userID, "hasStream", "true,stream=" + msg.stream)
handleUserStatusChange(status)
}
}
private def handleUserUnsharedWebcam(msg: UserUnsharedWebcam) {
if (msg.recorded) {
val status = UserStatusChange(msg.meetingID, msg.recorded,
msg.userID, "hasStream", "false,stream=" + msg.stream)
handleUserStatusChange(status)
}
}
private def handleUserStatusChange(msg: UserStatusChange): Unit = {
if (msg.recorded) {
val ev = new ParticipantStatusChangeRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setUserId(msg.userID);
ev.setMeetingId(msg.meetingID);
ev.setStatus(msg.status);
ev.setValue(msg.value.toString());
recorder.record(msg.meetingID, ev);
}
}
private def handleAssignPresenter(msg: PresenterAssigned): Unit = {
if (msg.recorded) {
val event = new AssignPresenterRecordEvent();
event.setMeetingId(msg.meetingID);
event.setTimestamp(TimestampGenerator.generateTimestamp);
event.setUserId(msg.presenter.presenterID);
event.setName(msg.presenter.presenterName);
event.setAssignedBy(msg.presenter.assignedBy);
recorder.record(msg.meetingID, event);
}
}
private def getPresentationId(whiteboardId: String): String = {
// Need to split the whiteboard id into presenation id and page num as the old
// recording expects them
val strId = new StringOps(whiteboardId)
val ids = strId.split('/')
var presId: String = ""
if (ids.length == 2) {
presId = ids(0)
}
presId
}
private def getPageNum(whiteboardId: String): String = {
val strId = new StringOps(whiteboardId)
val ids = strId.split('/')
var pageNum = "0"
if (ids.length == 2) {
pageNum = ids(1)
}
pageNum
}
private def handleSendWhiteboardAnnotationEvent(msg: SendWhiteboardAnnotationEvent) {
if (msg.recorded) {
if ((msg.shape.shapeType == WhiteboardKeyUtil.TEXT_TYPE) && (msg.shape.status != WhiteboardKeyUtil.TEXT_CREATED_STATUS)) {
val event = new ModifyTextWhiteboardRecordEvent()
event.setMeetingId(msg.meetingID)
event.setTimestamp(TimestampGenerator.generateTimestamp)
event.setPresentation(getPresentationId(msg.whiteboardId))
event.setPageNumber(getPageNum(msg.whiteboardId))
event.setWhiteboardId(msg.whiteboardId)
event.addAnnotation(mapAsJavaMap(msg.shape.shape))
recorder.record(msg.meetingID, event)
} else if ((msg.shape.shapeType == WhiteboardKeyUtil.POLL_RESULT_TYPE)) {
val event = new AddShapeWhiteboardRecordEvent()
event.setMeetingId(msg.meetingID)
event.setTimestamp(TimestampGenerator.generateTimestamp)
event.setPresentation(getPresentationId(msg.whiteboardId))
event.setPageNumber(getPageNum(msg.whiteboardId))
event.setWhiteboardId(msg.whiteboardId);
event.addAnnotation(mapAsJavaMap(msg.shape.shape))
recorder.record(msg.meetingID, event)
} else {
val event = new AddShapeWhiteboardRecordEvent()
event.setMeetingId(msg.meetingID)
event.setTimestamp(TimestampGenerator.generateTimestamp)
event.setPresentation(getPresentationId(msg.whiteboardId))
event.setPageNumber(getPageNum(msg.whiteboardId))
event.setWhiteboardId(msg.whiteboardId);
event.addAnnotation(mapAsJavaMap(msg.shape.shape))
recorder.record(msg.meetingID, event)
}
}
}
private def handleClearWhiteboardEvent(msg: ClearWhiteboardEvent) {
if (msg.recorded) {
val event = new ClearPageWhiteboardRecordEvent()
event.setMeetingId(msg.meetingID)
event.setTimestamp(TimestampGenerator.generateTimestamp)
event.setPresentation(getPresentationId(msg.whiteboardId))
event.setPageNumber(getPageNum(msg.whiteboardId))
event.setWhiteboardId(msg.whiteboardId)
recorder.record(msg.meetingID, event)
}
}
private def handleUndoWhiteboardEvent(msg: UndoWhiteboardEvent) {
if (msg.recorded) {
val event = new UndoShapeWhiteboardRecordEvent()
event.setMeetingId(msg.meetingID)
event.setTimestamp(TimestampGenerator.generateTimestamp)
event.setPresentation(getPresentationId(msg.whiteboardId))
event.setPageNumber(getPageNum(msg.whiteboardId))
event.setWhiteboardId(msg.whiteboardId)
event.setShapeId(msg.shapeId);
recorder.record(msg.meetingID, event)
}
}
private def handleEditCaptionHistoryReply(msg: EditCaptionHistoryReply) {
if (msg.recorded) {
val ev = new EditCaptionHistoryRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setMeetingId(msg.meetingID);
ev.setStartIndex(msg.startIndex.toString());
ev.setEndIndex(msg.endIndex.toString());
ev.setLocale(msg.locale);
ev.setLocaleCode(msg.localeCode);
ev.setText(msg.text);
recorder.record(msg.meetingID, ev);
}
}
private def handleDeskShareStartRTMPBroadcast(msg: DeskShareStartRTMPBroadcast) {
val event = new DeskShareStartRTMPRecordEvent()
event.setMeetingId(msg.conferenceName)
event.setStreamPath(msg.streamPath)
event.setTimestamp(TimestampGenerator.generateTimestamp)
log.info("handleDeskShareStartRTMPBroadcast " + msg.conferenceName)
recorder.record(msg.conferenceName, event)
}
private def handleDeskShareStopRTMPBroadcast(msg: DeskShareStopRTMPBroadcast) {
val event = new DeskShareStopRTMPRecordEvent()
event.setMeetingId(msg.conferenceName)
event.setStreamPath(msg.streamPath)
event.setTimestamp(TimestampGenerator.generateTimestamp)
log.info("handleDeskShareStopRTMPBroadcast " + msg.conferenceName)
recorder.record(msg.conferenceName, event)
}
private def handleDeskShareNotifyViewersRTMP(msg: DeskShareNotifyViewersRTMP) {
val event = new DeskShareNotifyViewersRTMPRecordEvent()
event.setMeetingId(msg.meetingID)
event.setStreamPath(msg.streamPath)
event.setBroadcasting(msg.broadcasting)
event.setTimestamp(TimestampGenerator.generateTimestamp)
log.info("handleDeskShareNotifyViewersRTMP " + msg.meetingID)
recorder.record(msg.meetingID, event)
}
}

View File

@ -1,19 +0,0 @@
package org.bigbluebutton.core
import akka.actor.ActorRef
import akka.actor.ActorContext
import org.bigbluebutton.core.api.MessageOutGateway
import org.bigbluebutton.core.bus._
object RunningMeeting {
def apply(mProps: MeetingProperties, outGW: OutMessageGateway,
eventBus: IncomingEventBus)(implicit context: ActorContext) =
new RunningMeeting(mProps, outGW, eventBus)(context)
}
class RunningMeeting(val mProps: MeetingProperties, val outGW: OutMessageGateway,
val eventBus: IncomingEventBus)(implicit val context: ActorContext) {
val actorRef = context.actorOf(MeetingActor.props(mProps, eventBus, outGW), mProps.meetingID)
}

View File

@ -39,6 +39,7 @@ object Constants {
val FORCE = "force"
val RESPONSE = "response"
val PRESENTATION_ID = "presentation_id"
val DOWNLOADABLE = "downloadable"
val X_OFFSET = "x_offset"
val Y_OFFSET = "y_offset"
val WIDTH_RATIO = "width_ratio"
@ -84,6 +85,8 @@ object Constants {
val SHAPES = "shapes"
val SHAPE = "shape"
val SHAPE_ID = "shape_id"
val MULTI_USER = "multi_user"
val FULL_CLEAR = "full_clear"
val PRESENTATION = "presentation"
val ID = "id"
val CURRENT = "current"
@ -98,4 +101,17 @@ object Constants {
val VIEWER_PASS = "viewer_pass"
val CREATE_TIME = "create_time"
val CREATE_DATE = "create_date"
val GUEST = "guest"
val WAITING_FOR_ACCEPTANCE = "waiting_for_acceptance"
val GUEST_POLICY = "guest_policy"
val GUESTS_WAITING = "guests_waiting"
val NOTE_ID = "note_id"
val NOTES = "notes"
val NOTE_NAME = "note_name"
val PATCH = "patch"
val PATCH_ID = "patch_id"
val UNDO = "undo"
val REDO = "redo"
val OPERATION = "operation"
val NOTE = "note"
}

View File

@ -1,12 +1,8 @@
package org.bigbluebutton.core.api
import org.bigbluebutton.core.api.Role._
import org.bigbluebutton.core.apps.AnnotationVO
import org.bigbluebutton.core.apps.Presentation
import org.bigbluebutton.core.MeetingProperties
import org.bigbluebutton.core.apps.BreakoutUser
import org.bigbluebutton.common2.msgs.BreakoutUserVO
import org.bigbluebutton.core.domain.{ BreakoutUser, BreakoutVoiceUser }
import spray.json.JsObject
case class InMessageHeader(name: String)
case class InHeaderAndJsonPayload(header: InMessageHeader, payload: JsObject)
case class MessageProcessException(message: String) extends Exception(message)
@ -22,174 +18,79 @@ case class IsMeetingActorAliveMessage(meetingId: String) extends InMessage
case class KeepAliveMessage(aliveID: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////
// Meeting
// Internal Messages
/////////////////////////////////////////////////////////////////////////////
case class MonitorNumberOfUsers(meetingID: String) extends InMessage
case class SendTimeRemainingUpdate(meetingId: String) extends InMessage
case class MonitorNumberOfUsersInternalMsg(meetingID: String) extends InMessage
/**
* Audit message sent to meeting to trigger updating clients of meeting time remaining.
* @param meetingId
*/
case class SendTimeRemainingAuditInternalMsg(meetingId: String) extends InMessage
case class ExtendMeetingDuration(meetingId: String, userId: String) extends InMessage
case class CreateMeeting(meetingID: String, mProps: MeetingProperties) extends InMessage
case class InitializeMeeting(meetingID: String, recorded: Boolean) extends InMessage
case class DestroyMeeting(meetingID: String) extends InMessage
case class DestroyMeetingInternalMsg(meetingId: String) extends InMessage
/**
* Sent by breakout room to parent meeting the breakout had ended.
* @param meetingId
*/
case class BreakoutRoomEndedInternalMsg(meetingId: String) extends InMessage
/**
* Sent by breakout room to parent meeting that breakout room has been created.
* @param parentId
* @param breakoutId
*/
case class BreakoutRoomCreatedInternalMsg(parentId: String, breakoutId: String) extends InMessage
/**
* Audit message to trigger breakout room to update parent meeting of list of users.
* @param parentId
* @param breakoutId
*/
case class SendBreakoutUsersAuditInternalMsg(parentId: String, breakoutId: String) extends InMessage
/**
* Send by breakout room to parent meeting with list of users in breakout room.
* @param parentId
* @param breakoutId
* @param users
*/
case class BreakoutRoomUsersUpdateInternalMsg(parentId: String, breakoutId: String,
users: Vector[BreakoutUser],
voiceUsers: Vector[BreakoutVoiceUser]) extends InMessage
/**
* Sent by parent meeting to breakout room to end breakout room.
* @param parentId
* @param breakoutId
*/
case class EndBreakoutRoomInternalMsg(parentId: String, breakoutId: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////
// Meeting
/////////////////////////////////////////////////////////////////////////////
case class StartMeeting(meetingID: String) extends InMessage
case class EndMeeting(meetingId: String) extends InMessage
case class LockSetting(meetingID: String, locked: Boolean, settings: Map[String, Boolean]) extends InMessage
//////////////////////////////////////////////////////////////////////////////////////
// Breakout room
/////////////////////////////////////////////////////////////////////////////////////
// Sent by user to request the breakout rooms list of a room
case class BreakoutRoomsListMessage(meetingId: String) extends InMessage
// Sent by user to request creation of breakout rooms
case class CreateBreakoutRooms(meetingId: String, durationInMinutes: Int, record: Boolean, rooms: Vector[BreakoutRoomInPayload]) extends InMessage
case class BreakoutRoomInPayload(name: String, sequence: Int, users: Vector[String])
// Sent by user to request for a join URL in order to be able to join a breakout room
case class RequestBreakoutJoinURLInMessage(meetingId: String, breakoutMeetingId: String, userId: String) extends InMessage
// Sent by breakout actor to tell meeting actor that breakout room has been created.
case class BreakoutRoomCreated(meetingId: String, breakoutRoomId: String) extends InMessage
// Sent by breakout actor to tell meeting actor the list of users in the breakout room.
case class BreakoutRoomUsersUpdate(meetingId: String, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends InMessage
// Send by internal actor to tell the breakout actor to send it's list of users to the main meeting actor.
case class SendBreakoutUsersUpdate(meetingId: String) extends InMessage
// Sent by user to request ending all the breakout rooms
case class EndAllBreakoutRooms(meetingId: String) extends InMessage
// Sent by breakout actor to tell meeting actor that breakout room has been ended
case class BreakoutRoomEnded(meetingId: String, breakoutRoomId: String) extends InMessage
// Sent by user actor to ask for voice conference transfer
case class TransferUserToMeetingRequest(meetingId: String, targetMeetingId: String, userId: String) extends InMessage
////////////////////////////////////////////////////////////////////////////////////
// Lock
///////////////////////////////////////////////////////////////////////////////////
case class LockUser(meetingID: String, userId: String, lock: Boolean) extends InMessage
case class InitLockSettings(meetingID: String, settings: Permissions) extends InMessage
case class SetLockSettings(meetingID: String, setByUser: String, settings: Permissions) extends InMessage
case class GetLockSettings(meetingID: String, userId: String) extends InMessage
case class UpdateMeetingExpireMonitor(meetingID: String, hasUser: Boolean) extends InMessage
//////////////////////////////////////////////////////////////////////////////////
// Users
/////////////////////////////////////////////////////////////////////////////////
case class ValidateAuthToken(meetingID: String, userId: String, token: String,
correlationId: String, sessionId: String) extends InMessage
case class RegisterUser(meetingID: String, userID: String, name: String, role: Role,
extUserID: String, authToken: String, avatarURL: String) extends InMessage
case class UserJoining(meetingID: String, userID: String, authToken: String) extends InMessage
case class UserLeaving(meetingID: String, userID: String, sessionId: String) extends InMessage
case class GetUsers(meetingID: String, requesterID: String) extends InMessage
case class UserEmojiStatus(meetingID: String, userId: String, emojiStatus: String) extends InMessage
case class EjectUserFromMeeting(meetingID: String, userId: String, ejectedBy: String) extends InMessage
case class UserShareWebcam(meetingID: String, userId: String, stream: String) extends InMessage
case class UserUnshareWebcam(meetingID: String, userId: String, stream: String) extends InMessage
case class ChangeUserStatus(meetingID: String, userID: String, status: String, value: Object) extends InMessage
case class AssignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String) extends InMessage
case class SetRecordingStatus(meetingID: String, userId: String, recording: Boolean) extends InMessage
case class GetRecordingStatus(meetingID: String, userId: String) extends InMessage
case class AllowUserToShareDesktop(meetingID: String, userID: String) extends InMessage
case class ActivityResponse(meetingID: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////////
// Chat
/////////////////////////////////////////////////////////////////////////////////
case class GetChatHistoryRequest(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class SendPublicMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage
case class SendPrivateMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage
case class UserConnectedToGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
userid: String, name: String) extends InMessage
case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
userid: String, name: String) extends InMessage
///////////////////////////////////////////////////////////////////////////////////////
// Layout
//////////////////////////////////////////////////////////////////////////////////////
case class GetCurrentLayoutRequest(meetingID: String, requesterID: String) extends InMessage
case class SetLayoutRequest(meetingID: String, requesterID: String, layoutID: String) extends InMessage
case class LockLayoutRequest(meetingID: String, setById: String, lock: Boolean, viewersOnly: Boolean,
layout: Option[String]) extends InMessage
case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////////////
// Presentation
/////////////////////////////////////////////////////////////////////////////////////
case class ClearPresentation(meetingID: String) extends InMessage
case class RemovePresentation(meetingID: String, presentationID: String) extends InMessage
case class GetPresentationInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class SendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) extends InMessage
case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double,
widthRatio: Double, heightRatio: Double) extends InMessage
case class GotoSlide(meetingID: String, page: String) extends InMessage
case class SharePresentation(meetingID: String, presentationID: String, share: Boolean) extends InMessage
case class GetSlideInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class PreuploadedPresentations(meetingID: String, presentations: Seq[Presentation]) extends InMessage
case class PresentationConversionUpdate(meetingID: String, messageKey: String, code: String,
presentationId: String, presName: String) extends InMessage
case class PresentationPageCountError(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, maxNumberPages: Int, presName: String) extends InMessage
case class PresentationSlideGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, pagesCompleted: Int, presName: String) extends InMessage
case class PresentationConversionCompleted(meetingID: String, messageKey: String, code: String,
presentation: Presentation) extends InMessage
/////////////////////////////////////////////////////////////////////////////////////
// Polling
////////////////////////////////////////////////////////////////////////////////////
//case class CreatePollRequest(meetingID: String, requesterId: String, pollId: String, pollType: String) extends InMessage
case class StartCustomPollRequest(meetingID: String, requesterId: String, pollType: String, answers: Seq[String]) extends InMessage
case class StartPollRequest(meetingID: String, requesterId: String, pollType: String) extends InMessage
case class StopPollRequest(meetingID: String, requesterId: String) extends InMessage
case class ShowPollResultRequest(meetingID: String, requesterId: String, pollId: String) extends InMessage
case class HidePollResultRequest(meetingID: String, requesterId: String, pollId: String) extends InMessage
case class RespondToPollRequest(meetingID: String, requesterId: String, pollId: String, questionId: Int, answerId: Int) extends InMessage
case class GetPollRequest(meetingID: String, requesterId: String, pollId: String) extends InMessage
case class GetCurrentPollRequest(meetingID: String, requesterId: String) extends InMessage
///////////////////////////////////////////////////////////////////////////////////
// Voice
///////////////////////////////////////////////////////////////////////////////////
case class InitAudioSettings(meetingID: String, requesterID: String, muted: Boolean) extends InMessage
case class SendVoiceUsersRequest(meetingID: String, requesterID: String) extends InMessage
case class MuteAllExceptPresenterRequest(meetingID: String, requesterID: String, mute: Boolean) extends InMessage
case class MuteMeetingRequest(meetingID: String, requesterID: String, mute: Boolean) extends InMessage
case class IsMeetingMutedRequest(meetingID: String, requesterID: String) extends InMessage
case class MuteUserRequest(meetingID: String, requesterID: String, userID: String, mute: Boolean) extends InMessage
case class LockUserRequest(meetingID: String, requesterID: String, userID: String, lock: Boolean) extends InMessage
case class EjectUserFromVoiceRequest(meetingID: String, userId: String, ejectedBy: String) extends InMessage
case class VoiceUserJoinedMessage(meetingID: String, user: String, voiceConfId: String,
callerIdNum: String, callerIdName: String, muted: Boolean, talking: Boolean) extends InMessage
case class UserJoinedVoiceConfMessage(voiceConfId: String, voiceUserId: String, userId: String, externUserId: String,
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean, avatarURL: String, listenOnly: Boolean) extends InMessage
case class UserLeftVoiceConfMessage(voiceConfId: String, voiceUserId: String) extends InMessage
case class UserLockedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, locked: Boolean) extends InMessage
case class UserMutedInVoiceConfMessage(voiceConfId: String, voiceUserId: String, muted: Boolean) extends InMessage
case class UserTalkingInVoiceConfMessage(voiceConfId: String, voiceUserId: String, talking: Boolean) extends InMessage
case class VoiceConfRecordingStartedMessage(voiceConfId: String, recordStream: String, recording: Boolean, timestamp: String) extends InMessage
/////////////////////////////////////////////////////////////////////////////////////
// Whiteboard
/////////////////////////////////////////////////////////////////////////////////////
case class SendWhiteboardAnnotationRequest(meetingID: String, requesterID: String, annotation: AnnotationVO) extends InMessage
case class GetWhiteboardShapesRequest(meetingID: String, requesterID: String, whiteboardId: String, replyTo: String) extends InMessage
case class ClearWhiteboardRequest(meetingID: String, requesterID: String, whiteboardId: String) extends InMessage
case class UndoWhiteboardRequest(meetingID: String, requesterID: String, whiteboardId: String) extends InMessage
case class EnableWhiteboardRequest(meetingID: String, requesterID: String, enable: Boolean) extends InMessage
case class IsWhiteboardEnabledRequest(meetingID: String, requesterID: String, replyTo: String) extends InMessage
// No idea what part this is for
case class GetAllMeetingsRequest(meetingID: String /** Not used. Just to satisfy trait **/ ) extends InMessage
// Caption
case class SendCaptionHistoryRequest(meetingID: String, requesterID: String) extends InMessage
case class UpdateCaptionOwnerRequest(meetingID: String, locale: String, localeCode: String, ownerID: String) extends InMessage
case class EditCaptionHistoryRequest(meetingID: String, userID: String, startIndex: Integer, endIndex: Integer, locale: String, localeCode: String, text: String) extends InMessage
// DeskShare
case class DeskShareStartedRequest(conferenceName: String, callerId: String, callerIdName: String) extends InMessage
case class DeskShareStoppedRequest(conferenceName: String, callerId: String, callerIdName: String) extends InMessage
case class DeskShareRTMPBroadcastStartedRequest(conferenceName: String, streamname: String, videoWidth: Int, videoHeight: Int, timestamp: String) extends InMessage
case class DeskShareRTMPBroadcastStoppedRequest(conferenceName: String, streamname: String, videoWidth: Int, videoHeight: Int, timestamp: String) extends InMessage
case class DeskShareGetDeskShareInfoRequest(conferenceName: String, requesterID: String, replyTo: String) extends InMessage

View File

@ -24,11 +24,13 @@ object MessageNames {
val USER_SHARE_WEBCAM = "user_share_webcam_request"
val USER_UNSHARE_WEBCAM = "user_unshare_webcam_request"
val CHANGE_USER_STATUS = "change_user_status_request"
val CHANGE_USER_ROLE = "change_user_role"
val ASSIGN_PRESENTER = "assign_presenter_request"
val SET_RECORDING_STATUS = "set_recording_status_request"
val GET_CHAT_HISTORY = "get_chat_history_request"
val SEND_PUBLIC_MESSAGE = "send_public_chat_message_request"
val SEND_PRIVATE_MESSAGE = "send_private_chat_message_request"
val CLEAR_PUBLIC_CHAT_HISTORY = "clear_public_chat_history_request"
val GET_CURRENT_LAYOUT = "get_current_layout_request"
val SET_LAYOUT = "set_layout_request"
val BROADCAST_LAYOUT = "broadcast_layout_request"
@ -60,7 +62,6 @@ object MessageNames {
val PRESENTATION_PAGE_COUNT_ERROR = "presentation_page_count_error_message"
val PRESENTATION_SLIDE_GENERATED = "presentation_slide_generated_message"
val PRESENTATION_CONVERSION_COMPLETED = "presentation_conversion_completed_message"
val PRESENTATION_CURSOR_UPDATED = "presentation_cursor_updated_message"
val SEND_VOICE_USERS_REQUEST = "send_voice_users_request"
val MUTE_MEETING_REQUEST = "mute_meeting_request"
val IS_MEETING_MUTED = "is_meeting_muted_request"
@ -73,12 +74,9 @@ object MessageNames {
val VOICE_USER_MUTED = "voice_user_muted_message"
val VOICE_USER_TALKING = "voice_user_talking_message"
val VOICE_RECORDING = "voice_recording_message"
val SEND_WHITEBOARD_ANNOTATION = "send_whiteboard_annotation_request"
val GET_WHITEBOARD_SHAPES = "get_whiteboard_shapes_request"
val CLEAR_WHITEBOARD = "clear_whiteboard_request"
val UNDO_WHITEBOARD = "undo_whiteboard_request"
val ENABLE_WHITEBOARD = "enable_whiteboard_request"
val IS_WHITEBOARD_ENABLED = "is_whiteboard_enabled_request"
var GET_GUEST_POLICY = "get_guest_policy"
val SET_GUEST_POLICY = "set_guest_policy"
val RESPOND_TO_GUEST = "respond_to_guest"
val GET_ALL_MEETINGS_REQUEST = "get_all_meetings_request"
// OUT MESSAGES
@ -112,6 +110,7 @@ object MessageNames {
val USER_SHARED_WEBCAM = "user_shared_webcam_message"
val USER_UNSHARED_WEBCAM = "user_unshared_webcam_message"
val USER_STATUS_CHANGED = "user_status_changed_message"
val USER_ROLE_CHANGED = "user_role_change"
val MUTE_VOICE_USER = "mute_voice_user_request"
val USER_VOICE_MUTED = "user_voice_muted_message"
val USER_VOICE_TALKING = "user_voice_talking_message"
@ -124,6 +123,7 @@ object MessageNames {
val GET_CHAT_HISTORY_REPLY = "get_chat_history_reply"
val SEND_PUBLIC_CHAT_MESSAGE = "send_public_chat_message"
val SEND_PRIVATE_CHAT_MESSAGE = "send_private_chat_message"
val CLEAR_PUBLIC_CHAT_HISTORY_REPLY = "clear_public_chat_history_reply"
val GET_CURRENT_LAYOUT_REPLY = "get_current_layout_reply"
val SET_LAYOUT_REPLY = "set_layout_reply"
val BROADCAST_LAYOUT_REPLY = "broadcast_layout_reply"
@ -154,20 +154,17 @@ object MessageNames {
val GET_PRESENTATION_STATUS_REPLY = "get_presentation_status_reply"
val PRESENTATION_REMOVED_MESSAGE = "presentation_removed_message"
val PRESENTATION_PAGE_GENERATED = "presentation_page_generated_message"
val GET_WHITEBOARD_SHAPES_REPLY = "get_whiteboard_shapes_reply"
val SEND_WHITEBOARD_SHAPE = "send_whiteboard_shape_message"
val UNDO_WHITEBOARD_MESSAGE = "undo_whiteboard_message"
val WHITEBOARD_ENABLED = "whiteboard_enabled_message"
val WHITEBOARD_CLEARED = "whiteboard_cleared_message"
val IS_WHITEBOARD_ENABLED_REPLY = "is_whiteboard_enabled_reply"
val MEETING_DESTROYED_EVENT = "meeting_destroyed_event"
val KEEP_ALIVE_REPLY = "keep_alive_reply"
val USER_LISTEN_ONLY = "user_listening_only"
val GET_ALL_MEETINGS_REPLY = "get_all_meetings_reply_message"
val EDIT_CAPTION_HISTORY = "edit_caption_history_message"
val UPDATE_CAPTION_OWNER = "update_caption_owner_message"
val SEND_CAPTION_HISTORY_REPLY = "send_caption_history_reply_message"
// breakout rooms
val BREAKOUT_ROOM_STARTED = "BreakoutRoomStarted"
var GET_GUEST_POLICY_REPLY = "get_guest_policy_reply"
val GUEST_POLICY_CHANGED = "guest_policy_changed"
val GUEST_ACCESS_DENIED = "guest_access_denied"
val INACTIVITY_WARNING = "inactivity_warning_message"
val MEETING_IS_ACTIVE = "meeting_is_active_message"
}

View File

@ -1,163 +1,38 @@
package org.bigbluebutton.core.api
import org.bigbluebutton.core.apps.AnnotationVO
import org.bigbluebutton.core.apps.CurrentPresentationInfo
import org.bigbluebutton.core.apps.Presentation
import org.bigbluebutton.core.apps.Page
import org.bigbluebutton.core.MeetingProperties
import org.bigbluebutton.core.apps.PollVO
import org.bigbluebutton.core.apps.SimplePollOutVO
import org.bigbluebutton.core.apps.SimplePollResultOutVO
import org.bigbluebutton.core.apps.BreakoutUser
case class VoiceRecordingStarted(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
case class MeetingEnding(meetingID: String) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
case class MeetingHasEnded(meetingID: String, userId: String) extends IOutMessage
case class MeetingDestroyed(meetingID: String) extends IOutMessage
case class DisconnectAllUsers(meetingID: String) extends IOutMessage
case class DisconnectUser(meetingID: String, userId: String) extends IOutMessage
case class KeepAliveMessageReply(aliveID: String) extends IOutMessage
case class PubSubPong(system: String, timestamp: Long) extends IOutMessage
case object IsAliveMessage extends IOutMessage
// Breakout Rooms
case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomBody], roomsReady: Boolean) extends IOutMessage
case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage
case class EndBreakoutRoom(breakoutMeetingId: String) extends IOutMessage
case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, redirectJoinURL: String, noRedirectJoinURL: String) extends IOutMessage
case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage
case class BreakoutRoomBody(name: String, externalMeetingId: String, meetingId: String, sequence: Int)
case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends IOutMessage
case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomEndedOutMessage(parentMeetingId: String, meetingId: String) extends IOutMessage
// Permissions
case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage
case class NewPermissionsSetting(meetingID: String, setByUser: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage
case class UserLocked(meetingID: String, userId: String, lock: Boolean) extends IOutMessage
case class GetPermissionsSettingReply(meetingID: String, userId: String) extends IOutMessage
// Users
case class UserRegistered(meetingID: String, recorded: Boolean, user: RegisteredUser) extends IOutMessage
case class UserLeft(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserEjectedFromMeeting(meetingID: String, recorded: Boolean, userId: String, ejectedBy: String) extends IOutMessage
case class PresenterAssigned(meetingID: String, recorded: Boolean, presenter: Presenter) extends IOutMessage
case class EjectAllVoiceUsers(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class EndAndKickAll(meetingID: String, recorded: Boolean) extends IOutMessage
case class GetUsersReply(meetingID: String, requesterID: String, users: Array[UserVO]) extends IOutMessage
case class ValidateAuthTokenTimedOut(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class ValidateAuthTokenReply(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class UserJoined(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserChangedEmojiStatus(meetingID: String, recorded: Boolean, emojiStatus: String, userID: String) extends IOutMessage
case class UserListeningOnly(meetingID: String, recorded: Boolean, userID: String, listenOnly: Boolean) extends IOutMessage
case class UserSharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserUnsharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserStatusChange(meetingID: String, recorded: Boolean, userID: String, status: String, value: Object) extends IOutMessage
case class GetUsersInVoiceConference(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class MuteVoiceUser(meetingID: String, recorded: Boolean, requesterID: String,
userId: String, voiceConfId: String, voiceUserId: String, mute: Boolean) extends IOutMessage
case class UserVoiceMuted(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserVoiceTalking(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class EjectVoiceUser(meetingID: String, recorded: Boolean, requesterID: String, userId: String, voiceConfId: String, voiceUserId: String) extends IOutMessage
case class TransferUserToMeeting(voiceConfId: String, targetVoiceConfId: String, userId: String) extends IOutMessage
case class UserJoinedVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserLeftVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class AllowUserToShareDesktopOut(meetingID: String, userID: String, allowed: Boolean) extends IOutMessage
// Voice
case class IsMeetingMutedReply(meetingID: String, recorded: Boolean, requesterID: String, meetingMuted: Boolean) extends IOutMessage
case class StartRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
case class StartRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class StopRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String, recordedStream: String) extends IOutMessage
case class StopRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
// Chat
case class GetChatHistoryReply(meetingID: String, recorded: Boolean, requesterID: String,
replyTo: String, history: Array[Map[String, String]]) extends IOutMessage
case class SendPublicMessageEvent(meetingID: String, recorded: Boolean, requesterID: String,
message: Map[String, String]) extends IOutMessage
case class SendPrivateMessageEvent(meetingID: String, recorded: Boolean, requesterID: String,
message: Map[String, String]) extends IOutMessage
// Layout
case class GetCurrentLayoutReply(meetingID: String, recorded: Boolean, requesterID: String, layoutID: String,
locked: Boolean, setByUserID: String) extends IOutMessage
case class BroadcastLayoutEvent(meetingID: String, recorded: Boolean, requesterID: String,
layoutID: String, locked: Boolean, setByUserID: String, applyTo: Array[UserVO]) extends IOutMessage
case class LockLayoutEvent(meetingID: String, recorded: Boolean, setById: String, locked: Boolean,
applyTo: Array[UserVO]) extends IOutMessage
// Presentation
case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage
case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String,
info: CurrentPresentationInfo, replyTo: String) extends IOutMessage
case class SendCursorUpdateOutMsg(meetingID: String, recorded: Boolean, xPercent: Double, yPercent: Double) extends IOutMessage
case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentation: Presentation) extends IOutMessage
case class GetSlideInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, page: Page, replyTo: String) extends IOutMessage
case class GetPreuploadedPresentationsOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class PresentationConversionProgress(meetingID: String, messageKey: String, code: String,
presentationId: String, presentationName: String) extends IOutMessage
case class PresentationConversionError(meetingID: String, messageKey: String, code: String,
presentationId: String, numberOfPages: Int, maxNumberPages: Int, presentationName: String) extends IOutMessage
case class PresentationPageGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, pagesCompleted: Int, presentationName: String) extends IOutMessage
case class PresentationConversionDone(meetingID: String, recorded: Boolean, messageKey: String, code: String,
presentation: Presentation) extends IOutMessage
case class PresentationChanged(meetingID: String, presentation: Presentation) extends IOutMessage
case class GetPresentationStatusReply(meetingID: String, presentations: Seq[Presentation], current: Presentation, replyTo: String) extends IOutMessage
case class PresentationRemoved(meetingID: String, presentationId: String) extends IOutMessage
case class PageChanged(meetingID: String, page: Page) extends IOutMessage
// Polling
//case class PollCreatedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: PollVO) extends IOutMessage
//case class CreatePollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String, pollType: String) extends IOutMessage
case class PollStartedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollOutVO) extends IOutMessage
case class StartPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollStoppedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class StopPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String) extends IOutMessage
case class PollShowResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class ShowPollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollHideResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class HidePollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class UserRespondedToPollMessage(meetingID: String, recorded: Boolean, presenterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class RespondToPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class GetCurrentPollReplyMessage(meetingID: String, recorded: Boolean, requesterId: String, hasPoll: Boolean, poll: Option[PollVO]) extends IOutMessage
// Whiteboard
case class GetWhiteboardShapesReply(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shapes: Array[AnnotationVO], replyTo: String) extends IOutMessage
case class SendWhiteboardAnnotationEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shape: AnnotationVO) extends IOutMessage
case class ClearWhiteboardEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String) extends IOutMessage
case class UndoWhiteboardEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shapeId: String) extends IOutMessage
case class WhiteboardEnabledEvent(meetingID: String, recorded: Boolean, requesterID: String, enable: Boolean) extends IOutMessage
case class IsWhiteboardEnabledReply(meetingID: String, recorded: Boolean, requesterID: String, enabled: Boolean, replyTo: String) extends IOutMessage
case class GetAllMeetingsReply(meetings: Array[MeetingInfo]) extends IOutMessage
// Caption
case class SendCaptionHistoryReply(meetingID: String, recorded: Boolean, requesterID: String, history: Map[String, Array[String]]) extends IOutMessage
case class UpdateCaptionOwnerReply(meetingID: String, recorded: Boolean, locale: String, localeCode: String, ownerID: String) extends IOutMessage
case class EditCaptionHistoryReply(meetingID: String, recorded: Boolean, userID: String, startIndex: Integer, endIndex: Integer, locale: String, localeCode: String, text: String) extends IOutMessage
// DeskShare
case class DeskShareStartRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareStopRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareNotifyViewersRTMP(meetingID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareNotifyASingleViewer(meetingID: String, userID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareHangUp(meetingID: String, fsConferenceName: String) extends IOutMessage
// Value Objects
case class MeetingVO(id: String, recorded: Boolean)
package org.bigbluebutton.core.api
import org.bigbluebutton.core.apps._
import org.bigbluebutton.core.models._
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
case class MeetingEnding(meetingID: String) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
case class MeetingHasEnded(meetingID: String, userId: String) extends IOutMessage
case class MeetingDestroyed(meetingID: String) extends IOutMessage
case class DisconnectAllUsers(meetingID: String) extends IOutMessage
case class InactivityWarning(meetingID: String, duration: Long) extends IOutMessage
case class MeetingIsActive(meetingID: String) extends IOutMessage
case class DisconnectUser(meetingID: String, userId: String) extends IOutMessage
case class KeepAliveMessageReply(aliveID: String) extends IOutMessage
case class PubSubPong(system: String, timestamp: Long) extends IOutMessage
case object IsAliveMessage extends IOutMessage
// No idea what part this is for
case class GetAllMeetingsReply(meetings: Array[MeetingInfo]) extends IOutMessage
// DeskShare
case class DeskShareStartRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareStopRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareNotifyViewersRTMP(meetingID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareNotifyASingleViewer(meetingID: String, userID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareHangUp(meetingID: String, fsConferenceName: String) extends IOutMessage
//Transcode
case class StopMeetingTranscoders(meetingID: String) extends IOutMessage
// Value Objects
case class MeetingVO(id: String, recorded: Boolean)

View File

@ -2,10 +2,12 @@ package org.bigbluebutton.core.api
import java.lang.Boolean
object Role extends Enumeration {
type Role = Value
val MODERATOR = Value("MODERATOR")
val VIEWER = Value("VIEWER")
import org.bigbluebutton.core.models.GuestPolicyType
object Metadata extends Enumeration {
type Metadata = String
val INACTIVITY_DEADLINE = "inactivity-deadline"
val INACTIVITY_TIMELEFT = "inactivity-timeleft"
}
case class StatusCode(val code: Int, val text: String)
@ -33,93 +35,65 @@ object ErrorCodes {
case class RequestResult(status: StatusCode, errors: Option[Array[ErrorCode]])
case class Presenter(
presenterID: String,
presenterID: String,
presenterName: String,
assignedBy: String)
assignedBy: String
)
case class User(
id: String,
externId: String,
name: String,
moderator: Boolean,
avatarUrl: String,
logoutUrl: String,
presenter: Boolean,
callerId: CallerId,
id: String,
externId: String,
name: String,
moderator: Boolean,
avatarUrl: String,
logoutUrl: String,
presenter: Boolean,
callerId: CallerId,
phoneCaller: Boolean,
emojiStatus: String,
muted: Boolean,
talking: Boolean)
muted: Boolean,
talking: Boolean
)
case class CallerId(
name: String,
number: String)
name: String,
number: String
)
case class Permissions(
disableCam: Boolean = false,
disableMic: Boolean = false,
disablePrivChat: Boolean = false,
disablePubChat: Boolean = false,
lockedLayout: Boolean = false,
lockOnJoin: Boolean = false,
lockOnJoinConfigurable: Boolean = false)
case class RegisteredUser(
id: String,
externId: String,
name: String,
role: Role.Role,
authToken: String,
avatarURL: String)
disableCam: Boolean = false,
disableMic: Boolean = false,
disablePrivChat: Boolean = false,
disablePubChat: Boolean = false,
lockedLayout: Boolean = false,
lockOnJoin: Boolean = true,
lockOnJoinConfigurable: Boolean = false
)
case class Voice(
id: String,
webId: String,
callId: CallerId,
id: String,
webId: String,
callId: CallerId,
phoningIn: Boolean,
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean)
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean
)
case class UserVO(
userID: String,
externUserID: String,
name: String,
role: Role.Role,
emojiStatus: String,
presenter: Boolean,
hasStream: Boolean,
locked: Boolean,
webcamStreams: Set[String],
phoneUser: Boolean,
voiceUser: VoiceUser,
listenOnly: Boolean,
avatarURL: String,
joinedWeb: Boolean)
case class VoiceUser(
userId: String,
webUserId: String,
callerName: String,
callerNum: String,
joined: Boolean,
locked: Boolean,
muted: Boolean,
talking: Boolean,
avatarURL: String,
listenOnly: Boolean)
case class MeetingConfig(name: String,
id: MeetingID,
passwords: MeetingPasswords,
welcomeMsg: String,
logoutUrl: String,
maxUsers: Int,
record: Boolean = false,
duration: MeetingDuration,
defaultAvatarURL: String,
defaultConfigToken: String)
case class MeetingConfig(
name: String,
id: MeetingID,
passwords: MeetingPasswords,
welcomeMsg: String,
logoutUrl: String,
maxUsers: Int,
record: Boolean = false,
duration: MeetingDuration,
defaultAvatarURL: String,
defaultConfigToken: String,
guestPolicy: String = GuestPolicyType.ALWAYS_ACCEPT
)
case class MeetingName(name: String)
@ -130,11 +104,12 @@ case class VoiceConfig(telVoice: String, webVoice: String, dialNumber: String)
case class MeetingPasswords(moderatorPass: String, viewerPass: String)
case class MeetingDuration(duration: Int = 0, createdTime: Long = 0,
startTime: Long = 0, endTime: Long = 0)
startTime: Long = 0, endTime: Long = 0)
case class MeetingInfo(
meetingID: String,
meetingID: String,
meetingName: String,
recorded: Boolean,
recorded: Boolean,
voiceBridge: String,
duration: Long)
duration: Long
)

View File

@ -0,0 +1,77 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.domain.{ BreakoutRoom2x, BreakoutUser }
object BreakoutModel {
def create(
parentId: String,
id: String,
externalId: String,
name: String,
sequence: Integer,
voiceConf: String,
assignedUsers: Vector[String]
): BreakoutRoom2x = {
new BreakoutRoom2x(id, externalId, name, parentId, sequence, voiceConf, assignedUsers, Vector(), Vector(), None, false)
}
}
case class BreakoutModel(
startedOn: Option[Long],
durationInMinutes: Int,
rooms: Map[String, BreakoutRoom2x]
) {
def find(id: String): Option[BreakoutRoom2x] = {
rooms.get(id)
}
def findWithExternalId(externalId: String): Option[BreakoutRoom2x] = {
rooms.values find (r => r.externalId == externalId)
}
def getRooms(): Vector[BreakoutRoom2x] = {
rooms.values.toVector
}
def getNumberOfRooms(): Int = {
rooms.size
}
def started(room: BreakoutRoom2x, startedOnInMillis: Long): BreakoutRoom2x = {
room.copy(started = true, startedOn = Some(startedOnInMillis))
}
def hasAllStarted(): Boolean = {
rooms.values.filter(r => r.started).size == rooms.values.size
}
def update(room: BreakoutRoom2x): BreakoutModel = {
copy(rooms = rooms + (room.id -> room))
}
def getAssignedUsers(breakoutMeetingId: String): Option[Vector[String]] = {
for {
room <- rooms.get(breakoutMeetingId)
} yield room.assignedUsers
}
def updateBreakoutUsers(breakoutMeetingId: String, users: Vector[BreakoutUser]): BreakoutModel = {
val model = for {
room <- rooms.get(breakoutMeetingId)
} yield {
val newRoom = room.copy(users = users)
copy(rooms = rooms + (newRoom.id -> newRoom))
}
model match {
case Some(m) => m
case None => copy()
}
}
def removeRoom(id: String): BreakoutModel = {
copy(rooms = rooms - id)
}
}

View File

@ -1,235 +0,0 @@
package org.bigbluebutton.core.apps
import java.net.URLEncoder
import scala.collection.SortedSet
import scala.collection.mutable
import org.apache.commons.codec.digest.DigestUtils
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.core.LiveMeeting
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.bus.BigBlueButtonEvent
import org.bigbluebutton.core.bus.IncomingEventBus
trait BreakoutRoomApp extends SystemConfiguration {
this: LiveMeeting =>
val outGW: OutMessageGateway
val eventBus: IncomingEventBus
def handleBreakoutRoomsList(msg: BreakoutRoomsListMessage) {
val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.externalMeetingId, r.id, r.sequence) }
val roomsReady = breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0
log.info("Sending breakout rooms list to {} with containing {} room(s)", mProps.meetingID, breakoutRooms.length)
outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady))
}
def handleCreateBreakoutRooms(msg: CreateBreakoutRooms) {
// If breakout rooms are being created we ignore the coming message
if (breakoutModel.pendingRoomsNumber > 0) {
log.warning("CreateBreakoutRooms event received while {} are pending to be created for meeting {}", breakoutModel.pendingRoomsNumber, mProps.meetingID)
return
}
if (breakoutModel.getNumberOfRooms() > 0) {
log.warning("CreateBreakoutRooms event received while {} breakout rooms running for meeting {}", breakoutModel.getNumberOfRooms(), mProps.meetingID)
return
}
var i = 0
// in very rare cases the presentation conversion generates an error, what should we do?
// those cases where default.pdf is deleted from the whiteboard
val sourcePresentationId = if (!presModel.getCurrentPresentation().isEmpty) presModel.getCurrentPresentation().get.id else "blank"
val sourcePresentationSlide = if (!presModel.getCurrentPage().isEmpty) presModel.getCurrentPage().get.num else 0
breakoutModel.pendingRoomsNumber = msg.rooms.length;
for (room <- msg.rooms) {
i += 1
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(mProps.meetingID, i)
val voiceConfId = BreakoutRoomsUtil.createVoiceConfId(mProps.voiceBridge, i)
val r = breakoutModel.createBreakoutRoom(mProps.meetingID, breakoutMeetingId._1, breakoutMeetingId._2, room.name,
room.sequence, voiceConfId, room.users)
val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID, r.sequence,
r.voiceConfId, msg.durationInMinutes, mProps.moderatorPass, mProps.viewerPass,
sourcePresentationId, sourcePresentationSlide, msg.record)
outGW.send(new CreateBreakoutRoom(mProps.meetingID, p))
}
meetingModel.breakoutRoomsdurationInMinutes = msg.durationInMinutes;
meetingModel.breakoutRoomsStartedOn = timeNowInSeconds;
}
def sendJoinURL(userId: String, externalMeetingId: String, roomSequence: String) {
log.debug("Sending breakout meeting {} Join URL for user: {}", externalMeetingId, userId)
for {
user <- usersModel.getUser(userId)
apiCall = "join"
params = BreakoutRoomsUtil.joinParams(user.name, userId + "-" + roomSequence, true, externalMeetingId, mProps.moderatorPass)
// We generate a first url with redirect -> true
redirectBaseString = BreakoutRoomsUtil.createBaseString(params._1)
redirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, redirectBaseString, BreakoutRoomsUtil.calculateChecksum(apiCall, redirectBaseString, bbbWebSharedSecret))
// We generate a second url with redirect -> false
noRedirectBaseString = BreakoutRoomsUtil.createBaseString(params._2)
noRedirectJoinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, noRedirectBaseString, BreakoutRoomsUtil.calculateChecksum(apiCall, noRedirectBaseString, bbbWebSharedSecret))
} yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, externalMeetingId, userId, redirectJoinURL, noRedirectJoinURL))
}
def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) {
for {
breakoutRoom <- breakoutModel.getRoomWithExternalId(msg.breakoutMeetingId)
} yield sendJoinURL(msg.userId, msg.breakoutMeetingId, breakoutRoom.sequence.toString())
}
def handleBreakoutRoomCreated(msg: BreakoutRoomCreated) {
breakoutModel.pendingRoomsNumber -= 1
val room = breakoutModel.getBreakoutRoom(msg.breakoutRoomId)
room foreach { room =>
sendBreakoutRoomStarted(room.parentRoomId, room.name, room.externalMeetingId, room.id, room.sequence, room.voiceConfId)
}
// We postpone sending invitation until all breakout rooms have been created
if (breakoutModel.pendingRoomsNumber == 0) {
log.info("All breakout rooms created for meetingId={}", mProps.meetingID)
breakoutModel.getRooms().foreach { room =>
breakoutModel.getAssignedUsers(room.id) foreach { users =>
users.foreach { u =>
log.debug("Sending Join URL for users");
sendJoinURL(u, room.externalMeetingId, room.sequence.toString())
}
}
}
handleBreakoutRoomsList(new BreakoutRoomsListMessage(mProps.meetingID))
}
}
def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, externalMeetingId: String, breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
log.info("Sending breakout room started {} for parent meeting {} ", breakoutMeetingId, meetingId);
outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, externalMeetingId, breakoutMeetingId, sequence)))
}
def handleBreakoutRoomEnded(msg: BreakoutRoomEnded) {
breakoutModel.remove(msg.breakoutRoomId)
outGW.send(new BreakoutRoomEndedOutMessage(msg.meetingId, msg.breakoutRoomId))
}
def handleBreakoutRoomUsersUpdate(msg: BreakoutRoomUsersUpdate) {
breakoutModel.updateBreakoutUsers(msg.breakoutMeetingId, msg.users) foreach { room =>
outGW.send(new UpdateBreakoutUsersOutMessage(mProps.meetingID, mProps.recorded, msg.breakoutMeetingId, room.users))
}
}
def handleSendBreakoutUsersUpdate(msg: SendBreakoutUsersUpdate) {
val users = usersModel.getUsers().toVector
val breakoutUsers = users map { u => new BreakoutUser(u.externUserID, u.name) }
eventBus.publish(BigBlueButtonEvent(mProps.parentMeetingID,
new BreakoutRoomUsersUpdate(mProps.parentMeetingID, mProps.meetingID, breakoutUsers)))
}
def handleTransferUserToMeeting(msg: TransferUserToMeetingRequest) {
var targetVoiceBridge: String = msg.targetMeetingId
// If the current room is a parent room we fetch the voice bridge from the breakout room
if (!mProps.isBreakout) {
breakoutModel.getBreakoutRoom(msg.targetMeetingId) match {
case Some(b) => {
targetVoiceBridge = b.voiceConfId;
}
case None => // do nothing
}
} // if it is a breakout room, the target voice bridge is the same after removing the last digit
else {
targetVoiceBridge = mProps.voiceBridge.dropRight(1)
}
// We check the user from the mode
usersModel.getUser(msg.userId) match {
case Some(u) => {
if (u.voiceUser.joined) {
log.info("Transferring user userId=" + u.userID + " from voiceBridge=" + mProps.voiceBridge + " to targetVoiceConf=" + targetVoiceBridge)
outGW.send(new TransferUserToMeeting(mProps.voiceBridge, targetVoiceBridge, u.voiceUser.userId))
}
}
case None => // do nothing
}
}
def handleEndAllBreakoutRooms(msg: EndAllBreakoutRooms) {
log.info("EndAllBreakoutRooms event received for meetingId={}", mProps.meetingID)
breakoutModel.getRooms().foreach { room =>
outGW.send(new EndBreakoutRoom(room.id))
}
}
}
object BreakoutRoomsUtil {
def createMeetingIds(id: String, index: Int): (String, String) = {
val timeStamp = System.currentTimeMillis()
val externalHash = DigestUtils.sha1Hex(id.concat("-").concat(timeStamp.toString()).concat("-").concat(index.toString()))
val externalId = externalHash.concat("-").concat(timeStamp.toString())
val internalId = DigestUtils.sha1Hex(externalId).concat("-").concat(timeStamp.toString())
(internalId, externalId)
}
def createVoiceConfId(id: String, index: Int): String = {
id.concat(index.toString())
}
def createJoinURL(webAPI: String, apiCall: String, baseString: String, checksum: String): String = {
var apiURL = if (webAPI.endsWith("/")) webAPI else webAPI.concat("/")
apiURL.concat(apiCall).concat("?").concat(baseString).concat("&checksum=").concat(checksum)
}
//
//checksum() -- Return a checksum based on SHA-1 digest
//
def checksum(s: String): String = {
DigestUtils.sha1Hex(s);
}
def calculateChecksum(apiCall: String, baseString: String, sharedSecret: String): String = {
checksum(apiCall.concat(baseString).concat(sharedSecret))
}
def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutMeetingId: String,
password: String): (mutable.Map[String, String], mutable.Map[String, String]) = {
val params = collection.mutable.HashMap(
"fullName" -> urlEncode(username),
"userID" -> urlEncode(userId),
"isBreakout" -> urlEncode(isBreakout.toString()),
"meetingID" -> urlEncode(breakoutMeetingId),
"password" -> urlEncode(password))
(params += "redirect" -> urlEncode("true"), mutable.Map[String, String]() ++= params += "redirect" -> urlEncode("false"))
}
def sortParams(params: mutable.Map[String, String]): SortedSet[String] = {
collection.immutable.SortedSet[String]() ++ params.keySet
}
//From the list of parameters we want to pass. Creates a base string with parameters
//sorted in alphabetical order for us to sign.
def createBaseString(params: mutable.Map[String, String]): String = {
val csbuf = new StringBuffer()
val keys = sortParams(params)
var first = true;
for (key <- keys) {
for (value <- params.get(key)) {
if (first) {
first = false;
} else {
csbuf.append("&");
}
csbuf.append(key);
csbuf.append("=");
csbuf.append(value);
}
}
return csbuf.toString();
}
def urlEncode(s: String): String = {
URLEncoder.encode(s, "UTF-8");
}
}

View File

@ -1,58 +0,0 @@
package org.bigbluebutton.core.apps
import scala.Vector
case class BreakoutUser(id: String, name: String)
case class BreakoutRoom(id: String, externalMeetingId: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String,
assignedUsers: Vector[String], users: Vector[BreakoutUser])
class BreakoutRoomModel {
private var rooms = new collection.immutable.HashMap[String, BreakoutRoom]
var pendingRoomsNumber: Integer = 0
def add(room: BreakoutRoom): BreakoutRoom = {
rooms += room.id -> room
room
}
def remove(id: String) {
rooms -= id
}
def createBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, voiceConfId: String,
assignedUsers: Vector[String]): BreakoutRoom = {
val room = new BreakoutRoom(id, externalMeetingId, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector())
add(room)
}
def getBreakoutRoom(id: String): Option[BreakoutRoom] = {
rooms.get(id)
}
def getRoomWithExternalId(externalId: String): Option[BreakoutRoom] = {
rooms.values find (r => r.externalMeetingId == externalId)
}
def getRooms(): Array[BreakoutRoom] = {
rooms.values.toArray
}
def getNumberOfRooms(): Int = {
rooms.size
}
def getAssignedUsers(breakoutMeetingId: String): Option[Vector[String]] = {
for {
room <- rooms.get(breakoutMeetingId)
} yield room.assignedUsers
}
def updateBreakoutUsers(breakoutMeetingId: String, users: Vector[BreakoutUser]): Option[BreakoutRoom] = {
for {
room <- rooms.get(breakoutMeetingId)
newroom = room.copy(users = users)
room2 = add(newroom)
} yield room2
}
}

View File

@ -1,58 +0,0 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.api._
import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.core.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.LiveMeeting
trait CaptionApp {
this: LiveMeeting =>
val outGW: OutMessageGateway
def handleSendCaptionHistoryRequest(msg: SendCaptionHistoryRequest) {
var history = captionModel.getHistory()
//println("Caption history requested " + history)
outGW.send(new SendCaptionHistoryReply(mProps.meetingID, mProps.recorded, msg.requesterID, history))
}
def handleUpdateCaptionOwnerRequest(msg: UpdateCaptionOwnerRequest) {
// clear owner from previous locale
if (msg.ownerID.length > 0) {
captionModel.findLocaleByOwnerId(msg.ownerID).foreach(t => {
captionModel.changeTranscriptOwner(t, "")
// send notification that owner has changed
outGW.send(new UpdateCaptionOwnerReply(mProps.meetingID, mProps.recorded, t, captionModel.findLocaleCodeByLocale(t), ""))
})
}
// create the locale if it doesn't exist
if (captionModel.transcripts contains msg.locale) {
captionModel.changeTranscriptOwner(msg.locale, msg.ownerID)
} else { // change the owner if it does exist
captionModel.newTranscript(msg.locale, msg.localeCode, msg.ownerID)
}
outGW.send(new UpdateCaptionOwnerReply(mProps.meetingID, mProps.recorded, msg.locale, msg.localeCode, msg.ownerID))
}
def handleEditCaptionHistoryRequest(msg: EditCaptionHistoryRequest) {
captionModel.findLocaleByOwnerId(msg.userID).foreach(t => {
if (t == msg.locale) {
captionModel.editHistory(msg.startIndex, msg.endIndex, msg.locale, msg.text)
outGW.send(new EditCaptionHistoryReply(mProps.meetingID, mProps.recorded, msg.userID, msg.startIndex, msg.endIndex, msg.locale, msg.localeCode, msg.text))
}
})
}
def checkCaptionOwnerLogOut(userId: String) {
captionModel.findLocaleByOwnerId(userId).foreach(t => {
captionModel.changeTranscriptOwner(t, "")
// send notification that owner has changed
outGW.send(new UpdateCaptionOwnerReply(mProps.meetingID, mProps.recorded, t, captionModel.findLocaleCodeByLocale(t), ""))
})
}
}

View File

@ -1,61 +1,90 @@
package org.bigbluebutton.core.apps
import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.common2.msgs.TranscriptVO
import scala.collection.immutable.HashMap
class CaptionModel {
var transcripts = Map[String, Array[String]]()
private var transcripts = new HashMap[String, TranscriptVO]()
def newTranscript(locale: String, localeCode: String, ownerId: String) {
transcripts += locale -> Array(ownerId, "", localeCode)
private def createTranscript(locale: String, localeCode: String, ownerId: String): TranscriptVO = {
val transcript = TranscriptVO(ownerId, "", localeCode)
transcripts += locale -> transcript
transcript
}
def findLocaleByOwnerId(userId: String): Option[String] = {
transcripts.find(_._2(0) == userId).foreach(t => {
return Some(t._1)
private def findTranscriptByOwnerId(userId: String): Option[(String, TranscriptVO)] = {
transcripts.find(_._2.ownerId == userId).foreach(t => {
return Some(t)
})
return None
}
def findLocaleCodeByLocale(locale: String): String = {
def updateTranscriptOwner(locale: String, localeCode: String, ownerId: String): Map[String, TranscriptVO] = {
var updatedTranscripts = new HashMap[String, TranscriptVO]
// clear owner from previous locale
if (ownerId.length > 0) {
findTranscriptByOwnerId(ownerId).foreach(t => {
val oldTranscript = t._2.copy(ownerId = "")
transcripts += t._1 -> oldTranscript
updatedTranscripts += t._1 -> oldTranscript
})
}
// change the owner if it does exist
if (transcripts contains locale) {
return transcripts(locale)(2)
val newTranscript = transcripts(locale).copy(ownerId = ownerId)
transcripts += locale -> newTranscript
updatedTranscripts += locale -> newTranscript
} else { // create the locale if it doesn't exist
val addedTranscript = createTranscript(locale, localeCode, ownerId)
updatedTranscripts += locale -> addedTranscript
}
return ""
updatedTranscripts
}
def changeTranscriptOwner(locale: String, ownerId: String) {
if (transcripts contains locale) {
transcripts(locale)(0) = ownerId
}
def getHistory(): Map[String, TranscriptVO] = {
transcripts
}
def getHistory(): Map[String, Array[String]] = {
var history = Map[String, Array[String]]()
transcripts.foreach(t => {
history += t._1 -> Array(t._2(0), t._2(1), t._2(2))
})
history
}
def editHistory(startIndex: Integer, endIndex: Integer, locale: String, text: String) {
def editHistory(userId: String, startIndex: Integer, endIndex: Integer, locale: String, text: String): Boolean = {
var successfulEdit = false
//println("editHistory entered")
if (transcripts contains locale) {
//println("editHistory found locale:" + locale)
var oText: String = transcripts(locale)(1)
val oldTranscript = transcripts(locale)
if (oldTranscript.ownerId == userId) {
//println("editHistory found locale:" + locale)
val oText: String = transcripts(locale).text
if (startIndex >= 0 && endIndex <= oText.length && startIndex <= endIndex) {
//println("editHistory passed index test")
var sText: String = oText.substring(0, startIndex)
var eText: String = oText.substring(endIndex)
if (startIndex >= 0 && endIndex <= oText.length && startIndex <= endIndex) {
//println("editHistory passed index test")
val sText: String = oText.substring(0, startIndex)
val eText: String = oText.substring(endIndex)
transcripts(locale)(1) = (sText + text + eText)
//println("editHistory new history is: " + transcripts(locale)(1))
transcripts += locale -> transcripts(locale).copy(text = (sText + text + eText))
//println("editHistory new history is: " + transcripts(locale).text)
successfulEdit = true
}
}
}
successfulEdit
}
def checkCaptionOwnerLogOut(userId: String): Option[(String, TranscriptVO)] = {
var rtnTranscript: Option[(String, TranscriptVO)] = None
if (userId.length > 0) {
findTranscriptByOwnerId(userId).foreach(t => {
val oldTranscript = t._2.copy(ownerId = "")
transcripts += t._1 -> oldTranscript
rtnTranscript = Some((t._1, oldTranscript))
})
}
rtnTranscript
}
}

View File

@ -1,29 +0,0 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.api._
import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.LiveMeeting
trait ChatApp {
this: LiveMeeting =>
val outGW: OutMessageGateway
def handleGetChatHistoryRequest(msg: GetChatHistoryRequest) {
val history = chatModel.getChatHistory()
outGW.send(new GetChatHistoryReply(mProps.meetingID, mProps.recorded, msg.requesterID, msg.replyTo, history))
}
def handleSendPublicMessageRequest(msg: SendPublicMessageRequest) {
chatModel.addNewChatMessage(msg.message.toMap)
val pubMsg = msg.message.toMap
outGW.send(new SendPublicMessageEvent(mProps.meetingID, mProps.recorded, msg.requesterID, pubMsg))
}
def handleSendPrivateMessageRequest(msg: SendPrivateMessageRequest) {
val privMsg = msg.message.toMap
outGW.send(new SendPrivateMessageEvent(mProps.meetingID, mProps.recorded, msg.requesterID, privMsg))
}
}

Some files were not shown because too many files have changed in this diff Show More