Merge branch 'VRFS-19'

This commit is contained in:
Seth Call 2012-10-16 22:48:40 -05:00
commit 6650bf889a
6 changed files with 120 additions and 1 deletions

View File

@ -11,6 +11,8 @@ gem 'activerecord', '3.2.7'
gem 'uuidtools', '2.1.2'
gem 'bcrypt-ruby', '3.0.1'
gem 'ruby-protocol-buffers', '1.2.2'
gem 'eventmachine'
gem 'amqp'
group :test do
gem 'jam_db', :path=> "#{workspace}/jam-db/target/ruby_package"

View File

@ -1,7 +1,9 @@
require "pg"
require "active_record"
require "jampb"
require 'uuidtools'
require "uuidtools"
require "logging"
require "jam_ruby/mq_router"
require "jam_ruby/version"
require "jam_ruby/message_factory"
require "jam_ruby/models/music_session_client"

View File

@ -0,0 +1,6 @@
class ConnectionCleaner
def clean(connection, topic)
end
end

View File

@ -0,0 +1,3 @@
class PermissionError < Exception
end

58
lib/jam_ruby/mq_router.rb Normal file
View File

@ -0,0 +1,58 @@
require 'eventmachine'
class MQRouter
# monostate pattern:
# You can initialize MQRouter instances as you want,
# but ultimately there are internal static state variables to represent global MQ exchange connections
class << self
attr_accessor :client_exchange, :user_exchange
@@log = Logging.logger[MQRouter]
end
def access_music_session(music_session, user)
if music_session.nil?
raise ArgumentError, 'specified session not found'
end
if !music_session.access? user
raise PermissionError, 'not allowed to join the specified session'
end
return music_session
end
# sends a message to a session on behalf of a user
# if this is originating in the context of a client, it should be specified as :client_id => "value"
# client_msg should be a well-structure message (jam-pb message)
def user_publish_to_session(music_session, user, client_msg, sender = {:client_id => "" })
access_music_session(music_session, user)
# gather up client_ids in the session
client_ids = music_session.music_session_clients.map {|client| client.client_id }.reject {|client_id| client_id == sender[:client_id] }
publish_to_session(music_session.id, client_ids, client_msg.to_s, sender)
end
# sends a message to a session with no checking of permissions
# this method deliberately has no database interactivity/active_record objects
def publish_to_session(music_session_id, client_ids, client_msg, sender = {:client_id => "" })
EM.schedule do
sender_client_id = sender[:client_id]
# iterate over each person in the session, and send a p2p message
client_ids.each do |client_id|
@@log.debug "publishing to session:#{music_session_id} client:#{client_id} from client:#{sender_client_id}"
# put it on the topic exchange3 for clients
self.class.client_exchange.publish(client_msg, :routing_key => "client.#{client_id}")
end
end
end
end

View File

@ -0,0 +1,48 @@
require 'spec_helper'
describe MQRouter do
before do
@mq_router = MQRouter.new()
end
it "user_publish_to_session works (but faking MQ)" do
user1 = FactoryGirl.create(:user) # in the jam session
user2 = FactoryGirl.create(:user) # in the jam session
music_session = FactoryGirl.create(:music_session, :creator => user1)
music_session_member1 = FactoryGirl.create(:music_session_client, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
music_session_member2 = FactoryGirl.create(:music_session_client, :user => user2, :music_session => music_session, :ip_address => "2.2.2.2", :client_id => "2")
@mq_router.should_receive(:publish_to_session).with(music_session.id, [music_session_member2.client_id], "a message", :client_id => music_session_member1.client_id)
@mq_router.user_publish_to_session(music_session, user1, "a message" ,:client_id => music_session_member1.client_id)
end
it "user_publish_to_session works (checking exchange callbacks)" do
user1 = FactoryGirl.create(:user) # in the jam session
user2 = FactoryGirl.create(:user) # in the jam session
music_session = FactoryGirl.create(:music_session, :creator => user1)
music_session_member1 = FactoryGirl.create(:music_session_client, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
music_session_member2 = FactoryGirl.create(:music_session_client, :user => user2, :music_session => music_session, :ip_address => "2.2.2.2", :client_id => "2")
EM.run do
# mock up exchange
MQRouter.client_exchange = double("client_exchange")
MQRouter.client_exchange.should_receive(:publish).with("a message", :routing_key => "client.#{music_session_member2.client_id}")
@mq_router.user_publish_to_session(music_session, user1, "a message", :client_id => music_session_member1.client_id)
EM.stop
end
end
end