Package org.bigbluebutton.api.messaging

Source Code of org.bigbluebutton.api.messaging.RedisMessagingService

/**
* 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.api.messaging;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;

public class RedisMessagingService implements MessagingService {
  private static Logger log = LoggerFactory.getLogger(RedisMessagingService.class);
 
  private JedisPool redisPool;
  private final Set<MessageListener> listeners = new HashSet<MessageListener>();

  private final Executor exec = Executors.newSingleThreadExecutor();
  private Runnable pubsubListener;

   @Override
  public void addListener(MessageListener listener) {
     listeners.add(listener);
  }
  
  public void removeListener(MessageListener listener) {
     listeners.remove(listener);
   }

  public void recordMeetingInfo(String meetingId, Map<String, String> info) {
    Jedis jedis = redisPool.getResource();
    try {
        for (String key: info.keySet()) {
              log.debug("Storing metadata {} = {}", key, info.get(key));
        }  

        log.debug("Saving metadata in {}", meetingId);
      jedis.hmset("meeting:info:" + meetingId, info);
    } catch (Exception e){
      log.warn("Cannot record the info meeting:"+meetingId,e);
    } finally {
      redisPool.returnResource(jedis);
    }   
  }

  public void destroyMeeting(String meetingID) {
    HashMap<String,String> map = new HashMap<String, String>();
    map.put("messageId", MessagingConstants.DESTROY_MEETING_REQUEST_EVENT);
    map.put("meetingID", meetingID);
    Gson gson = new Gson();
   
    send(MessagingConstants.SYSTEM_CHANNEL, gson.toJson(map));   
  }
 
  public void createMeeting(String meetingID, Boolean recorded, String voiceBridge) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("messageId", MessagingConstants.CREATE_MEETING_REQUEST_EVENT);
    map.put("meetingID", meetingID);
    map.put("record", recorded);
    map.put("voiceBridge", voiceBridge);
   
    Gson gson = new Gson();
   
    send(MessagingConstants.SYSTEM_CHANNEL, gson.toJson(map));   
  }
 
  public void endMeeting(String meetingId) {
    HashMap<String,String> map = new HashMap<String, String>();
    map.put("messageId", MessagingConstants.END_MEETING_REQUEST_EVENT);
    map.put("meetingId", meetingId);
    Gson gson = new Gson();
    send(MessagingConstants.SYSTEM_CHANNEL, gson.toJson(map));
  }

  public void send(String channel, String message) {
    Jedis jedis = redisPool.getResource();
    try {
      log.debug("Sending to channel[" + channel + "] message[" + message + "]");
      jedis.publish(channel, message);
    } catch(Exception e){
      log.warn("Cannot publish the message to redis",e);
    }finally{
      redisPool.returnResource(jedis);
    }
  }

  public void sendPolls(String meetingId, String title, String question, String questionType, List<String> answers){
    Gson gson = new Gson();

    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("messageId", MessagingConstants.SEND_POLLS_EVENT);
    map.put("meetingId", meetingId);
    map.put("title", title);
    map.put("question", question);
    map.put("questionType", questionType);
    map.put("answers", answers);
   
    System.out.println(gson.toJson(map));
   
    send(MessagingConstants.POLLING_CHANNEL, gson.toJson(map));   
  }

  public String storeSubscription(String meetingId, String externalMeetingID, String callbackURL){
    String sid = "";
    Jedis jedis = redisPool.getResource();
    try {
      sid = Long.toString(jedis.incr("meeting:" + meetingId + ":nextSubscription"));

      HashMap<String,String> props = new HashMap<String,String>();
      props.put("subscriptionID", sid);
      props.put("meetingId", meetingId);
      props.put("externalMeetingID", externalMeetingID);
      props.put("callbackURL", callbackURL);
      props.put("active", "true");

      jedis.hmset("meeting:" + meetingId + ":subscription:" + sid, props);
      jedis.rpush("meeting:" + meetingId + ":subscriptions", sid);
     
    } catch (Exception e){
      log.warn("Cannot store subscription:" + meetingId, e);
    } finally {
      redisPool.returnResource(jedis);
    }

    return sid;  
  }

  public boolean removeSubscription(String meetingId, String subscriptionId){
    boolean unsubscribed = true;
    Jedis jedis = redisPool.getResource();
    try {
      jedis.hset("meeting:" + meetingId + ":subscription:" + subscriptionId, "active", "false")
    } catch (Exception e){
      log.warn("Cannot rmove subscription:" + meetingId, e);
      unsubscribed = false;
    } finally {
      redisPool.returnResource(jedis);
    }

    return unsubscribed;  
  }

  public List<Map<String,String>> listSubscriptions(String meetingId){
    List<Map<String,String>> list = new ArrayList<Map<String,String>>();
    Jedis jedis = redisPool.getResource();
    try {
      List<String> sids = jedis.lrange("meeting:" + meetingId + ":subscriptions", 0 , -1);
      for(int i=0; i<sids.size(); i++){
        Map<String,String> props = jedis.hgetAll("meeting:" + meetingId + ":subscription:" + sids.get(i));
        list.add(props)
      }
       
    } catch (Exception e){
      log.warn("Cannot list subscriptions:" + meetingId, e);
    } finally {
      redisPool.returnResource(jedis);
    }

    return list; 
 

  public void start() {
    log.debug("Starting redis pubsub...");   

    final Jedis jedis = redisPool.getResource();
    try {
      pubsubListener = new Runnable() {
          public void run() {
            jedis.psubscribe(new PubSubListener(), MessagingConstants.BIGBLUEBUTTON_PATTERN);            
          }
      };
      exec.execute(pubsubListener);
    } catch (Exception e) {
      log.error("Error in subscribe: " + e.getMessage());
    }
  }

  public void stop() {
    try {
      redisPool.destroy();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 
  public void setRedisPool(JedisPool redisPool){
    this.redisPool=redisPool;
  }
 
  private class PubSubListener extends JedisPubSub {
   
    public PubSubListener() {
      super();     
    }

    @Override
    public void onMessage(String channel, String message) {
      // Not used.
    }

    @Override
    public void onPMessage(String pattern, String channel, String message) {
      log.debug("Message Received in channel: " + channel);
      log.debug("Message: " + message);
     
      Gson gson = new Gson();
     
//      for (String key: map.keySet()) {
//        log.debug("rx: {} = {}", key, map.get(key));
//      }
     
      if(channel.equalsIgnoreCase(MessagingConstants.SYSTEM_CHANNEL)){
        HashMap<String,String> map = gson.fromJson(message, new TypeToken<Map<String, String>>() {}.getType());
        String messageId = map.get("messageID");
        log.debug("*** Message {}", messageId);

        for (MessageListener listener : listeners) {
          if(MessagingConstants.MEETING_STARTED_EVENT.equalsIgnoreCase(messageId)) {
            String meetingId = map.get("meetingID");
            listener.meetingStarted(meetingId);
          } else if(MessagingConstants.MEETING_ENDED_EVENT.equalsIgnoreCase(messageId)) {
            String meetingId = map.get("meetingID");
            listener.meetingEnded(meetingId);
          } else if(MessagingConstants.KEEP_ALIVE_REPLY_EVENT.equalsIgnoreCase(messageId)){
            String aliveId = map.get("aliveID");
            listener.keepAliveReply(aliveId);
          }
        }
      }
      else if(channel.equalsIgnoreCase(MessagingConstants.PARTICIPANTS_CHANNEL)){
        HashMap<String,String> map = gson.fromJson(message, new TypeToken<Map<String, String>>() {}.getType());
        String meetingId = map.get("meetingID");
        String messageId = map.get("messageID");
        if(MessagingConstants.USER_JOINED_EVENT.equalsIgnoreCase(messageId)){
          String internalUserId = map.get("internalUserID");
          String externalUserId = map.get("externalUserID");
          String fullname = map.get("fullname");
          String role = map.get("role");
         
          for (MessageListener listener : listeners) {
            listener.userJoined(meetingId, internalUserId, externalUserId, fullname, role);
          }
        } else if(MessagingConstants.USER_STATUS_CHANGE_EVENT.equalsIgnoreCase(messageId)){
          String internalUserId = map.get("internalUserID");
          String status = map.get("status");
          String value = map.get("value");
         
          for (MessageListener listener : listeners) {
            listener.updatedStatus(meetingId, internalUserId, status, value);
          }
        } else if(MessagingConstants.USER_LEFT_EVENT.equalsIgnoreCase(messageId)){
          String internalUserId = map.get("internalUserID");
         
          for (MessageListener listener : listeners) {
            listener.userLeft(meetingId, internalUserId);
          }
        }
      }
    }

    @Override
    public void onPSubscribe(String pattern, int subscribedChannels) {
      log.debug("Subscribed to the pattern:"+pattern);
    }

    @Override
    public void onPUnsubscribe(String pattern, int subscribedChannels) {
      // Not used.
    }

    @Override
    public void onSubscribe(String channel, int subscribedChannels) {
      // Not used.
    }

    @Override
    public void onUnsubscribe(String channel, int subscribedChannels) {
      // Not used.
    }   
  }

}
TOP

Related Classes of org.bigbluebutton.api.messaging.RedisMessagingService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.