* VRFS-18 completed by integrating ConnectionManager to REST API
* rescue_from used a little now; good way to handle errors
This commit is contained in:
parent
97f095fe03
commit
8837b29814
1
Gemfile
1
Gemfile
|
|
@ -29,6 +29,7 @@ group :development, :test do
|
|||
gem 'rspec-rails', '2.11.0'
|
||||
gem 'guard-rspec', '0.5.5'
|
||||
gem 'jasmine'
|
||||
gem 'pry'
|
||||
end
|
||||
|
||||
# Gems used only for assets and not required
|
||||
|
|
|
|||
|
|
@ -1,5 +1,23 @@
|
|||
class ApiMusicSessionsController < ApplicationController
|
||||
|
||||
# TODO: roll these into a base ApiController class?s
|
||||
rescue_from 'JamRuby::StateError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/state_error.rabl", :status => 500
|
||||
end
|
||||
rescue_from 'JamRuby::JamArgrumentError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/jam_argument_error.rabl", :status => 500
|
||||
end
|
||||
rescue_from 'JamRuby::PermissionError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/permission_error.rabl", :status => 500
|
||||
end
|
||||
|
||||
rescue_from 'ActiveRecord::RecordNotFound' do |exception|
|
||||
render :status => 404
|
||||
end
|
||||
|
||||
# have to be signed in currently to see this screen
|
||||
before_filter :signed_in_user
|
||||
|
||||
|
|
@ -8,6 +26,7 @@ class ApiMusicSessionsController < ApplicationController
|
|||
def initialize
|
||||
@mq_router = MQRouter.new
|
||||
@message_factory = MessageFactory.new
|
||||
|
||||
end
|
||||
|
||||
def index
|
||||
|
|
@ -15,10 +34,26 @@ class ApiMusicSessionsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@music_session = MusicSession.new()
|
||||
@music_session.creator = current_user
|
||||
@music_session.description = params[:description]
|
||||
@music_session.save
|
||||
ConnectionManager.active_record_transaction do |connection_manager|
|
||||
|
||||
client_id = params[:client_id]
|
||||
|
||||
if client_id.nil?
|
||||
raise JamArgumentError, "client_id must be specified"
|
||||
end
|
||||
|
||||
@music_session = MusicSession.new()
|
||||
@music_session.creator = current_user
|
||||
@music_session.description = params[:description]
|
||||
saved = @music_session.save
|
||||
|
||||
if saved
|
||||
# auto-join this user into the newly created session
|
||||
connection_manager.join_music_session(current_user.id, client_id, @music_session.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
respond_with @music_session, responder: ApiResponder, :location => api_session_detail_url(@music_session)
|
||||
end
|
||||
|
||||
|
|
@ -34,33 +69,50 @@ class ApiMusicSessionsController < ApplicationController
|
|||
end
|
||||
|
||||
def participant_show
|
||||
@music_session_client = MusicSessionClient.find(params[:id])
|
||||
@connection = Connection.find(params[:id])
|
||||
end
|
||||
|
||||
def participant_create
|
||||
@music_session = MusicSession.find(params[:id])
|
||||
@music_session = nil
|
||||
@connection = nil
|
||||
|
||||
client_id = params[:client_id]
|
||||
@music_session_client = MusicSessionClient.new()
|
||||
@music_session_client.ip_address = params[:ip_address]
|
||||
@music_session_client.client_id = client_id
|
||||
@music_session_client.music_session = @music_session
|
||||
@music_session_client.user = current_user
|
||||
saved = @music_session_client.save
|
||||
ConnectionManager.active_record_transaction do |connection_manager|
|
||||
@music_session = MusicSession.find(params[:id])
|
||||
|
||||
if saved
|
||||
# send out notification to queue to the rest of the session
|
||||
user_joined = @message_factory.user_joined_music_session(current_user.id, current_user.name)
|
||||
@mq_router.user_publish_to_session(@music_session, current_user, user_joined, sender = {:client_id => client_id})
|
||||
if @music_session.nil?
|
||||
raise JamArgumentError, "no session found"
|
||||
end
|
||||
|
||||
client_id = params[:client_id]
|
||||
|
||||
connection_manager.join_music_session(current_user.id, client_id, @music_session.id)
|
||||
|
||||
@connection = Connection.find_by_client_id(client_id)
|
||||
end
|
||||
|
||||
respond_with @music_session_client, responder: ApiResponder, :location => api_session_participant_detail_url(@music_session_client)
|
||||
# send out notification to queue to the rest of the session
|
||||
user_joined = @message_factory.user_joined_music_session(current_user.id, current_user.name)
|
||||
@mq_router.user_publish_to_session(@music_session, current_user, user_joined, sender = {:client_id => @connection.client_id})
|
||||
|
||||
respond_with @connection, responder: ApiResponder, :location => api_session_participant_detail_url(@connection.client_id)
|
||||
end
|
||||
|
||||
def participant_delete
|
||||
@music_session_client = MusicSessionClient.find(params[:id])
|
||||
@music_session_client.delete
|
||||
|
||||
respond_with @music_session_client, responder: ApiResponder
|
||||
ConnectionManager.active_record_transaction do |connection_manager|
|
||||
@connection = Connection.find_by_client_id(params[:client_id])
|
||||
|
||||
if @connection.nil?
|
||||
raise JamArgumentError, "no client found with specified client_id #{id}"
|
||||
end
|
||||
|
||||
if @connection.user.id != current_user.id
|
||||
raise PermissionError, "you do not own this connection"
|
||||
end
|
||||
|
||||
connection_manager.leave_music_session(current_user.id, @connection.client_id, @connection.music_session_id)
|
||||
end
|
||||
|
||||
respond_with @connection, responder: ApiResponder
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
object @music_session
|
||||
|
||||
extends "api_music_sessions/show"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
object @music_session_client
|
||||
object @connection
|
||||
|
||||
attributes :id, :ip_address, :client_id
|
||||
|
|
@ -2,7 +2,7 @@ object @music_session
|
|||
|
||||
attributes :id, :description
|
||||
|
||||
child(:music_session_clients => :participants) {
|
||||
child(:connections => :participants) {
|
||||
collection @music_sessions, :object_root => false
|
||||
attributes :id, :ip_address, :client_id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
object @exception
|
||||
|
||||
attributes :message
|
||||
|
||||
node "type" do
|
||||
"ArgumentError"
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
object @exception
|
||||
|
||||
attributes :message
|
||||
|
||||
node "type" do
|
||||
"PermissionError"
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
object @exception
|
||||
|
||||
attributes :message
|
||||
|
||||
node "type" do
|
||||
"StateError"
|
||||
end
|
||||
|
|
@ -25,8 +25,11 @@ test: &test
|
|||
timeout: 5000
|
||||
|
||||
production:
|
||||
adapter: sqlite3
|
||||
database: db/production.sqlite3
|
||||
adapter: postgresql
|
||||
database: jam
|
||||
username: postgres
|
||||
password: postgres
|
||||
host: localhost
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ SampleApp::Application.routes.draw do
|
|||
scope '/api' do
|
||||
# music sessions
|
||||
match '/sessions/:id/participants' => 'api_music_sessions#participant_create', :via => :post
|
||||
match '/participants/:id' => 'api_music_sessions#participant_show', :via => :get, :as => 'api_session_participant_detail'
|
||||
match '/participants/:id' => 'api_music_sessions#participant_delete', :via => :delete
|
||||
match '/participants/:client_id' => 'api_music_sessions#participant_show', :via => :get, :as => 'api_session_participant_detail'
|
||||
match '/participants/:client_id' => 'api_music_sessions#participant_delete', :via => :delete
|
||||
match '/sessions/:id' => 'api_music_sessions#show', :via => :get, :as => 'api_session_detail'
|
||||
match '/sessions/:id' => 'api_music_sessions#delete', :via => :delete
|
||||
match '/sessions' => 'api_music_sessions#index', :via => :get
|
||||
|
|
|
|||
|
|
@ -10,4 +10,8 @@ FactoryGirl.define do
|
|||
end
|
||||
end
|
||||
|
||||
factory :connection, :class => JamRuby::Connection do
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,7 +23,10 @@ describe "Music Session API ", :type => :api do
|
|||
|
||||
it "should create session" do
|
||||
# create the session
|
||||
post '/api/sessions.json', '{"description" : "a session"}', "CONTENT_TYPE" => 'application/json'
|
||||
# create a client connection
|
||||
|
||||
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "1")
|
||||
post '/api/sessions.json', '{"description" : "a session", "client_id" : "' + client.client_id + '"}', "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(201)
|
||||
|
||||
# now fetch it's data
|
||||
|
|
@ -44,7 +47,9 @@ describe "Music Session API ", :type => :api do
|
|||
list.length.should == 0
|
||||
|
||||
# create the session
|
||||
post '/api/sessions.json', '{"description" : "a session"}', "CONTENT_TYPE" => 'application/json'
|
||||
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "2")
|
||||
post '/api/sessions.json', '{"description" : "a session", "client_id" : "' + client.client_id + '"}', "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(201)
|
||||
|
||||
# now fetch it's data
|
||||
get last_response.headers["Location"]
|
||||
|
|
@ -65,43 +70,33 @@ describe "Music Session API ", :type => :api do
|
|||
|
||||
it "should add/remove member from session" do
|
||||
# create the session
|
||||
post '/api/sessions.json', '{"description" : "a session"}', "CONTENT_TYPE" => 'application/json'
|
||||
client = FactoryGirl.create(:connection, :user => user, :ip_address => "1.1.1.1", :client_id => "3")
|
||||
post '/api/sessions.json', '{"description" : "a session", "client_id" : "' + client.client_id + '"}', "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(201)
|
||||
|
||||
# now fetch it's data
|
||||
get last_response.headers["Location"]
|
||||
music_session = JSON.parse(last_response.body)
|
||||
music_session["participants"].length.should == 0
|
||||
|
||||
# create a member
|
||||
post "/api/sessions/#{music_session["id"]}/participants.json", '{ "ip_address" : "1.2.3.4", "client_id" : "1" }', "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(201)
|
||||
|
||||
musician = JSON.parse(last_response.body)
|
||||
|
||||
# re-fetch the session now that there is a musician
|
||||
get "/api/sessions/#{music_session["id"]}.json"
|
||||
music_session = JSON.parse(last_response.body)
|
||||
|
||||
# there should be one musician in the response
|
||||
# and the creator should be in the session
|
||||
music_session["participants"].length.should == 1
|
||||
musician = music_session["participants"][0]
|
||||
|
||||
# and that musician should have the same IP address
|
||||
musician["ip_address"].should == "1.2.3.4"
|
||||
musician["ip_address"].should == "1.1.1.1"
|
||||
|
||||
# and that musician should have the same IP address
|
||||
musician["client_id"].should == "1"
|
||||
# and that musician should have the correct IP address
|
||||
musician["client_id"].should == "3"
|
||||
|
||||
# now delete that musician
|
||||
delete "/api/participants/#{musician["id"]}.json", '', "CONTENT_TYPE" => 'application/json'
|
||||
delete "/api/participants/#{musician["client_id"]}.json", '', "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(204)
|
||||
|
||||
# re-fetch the session now that there is not a musician
|
||||
# re-fetch the session now that there is not a musician;
|
||||
# we auto-delete sessions when the last person leaves
|
||||
get "/api/sessions/#{music_session["id"]}.json"
|
||||
music_session = JSON.parse(last_response.body)
|
||||
last_response.status.should eql(404)
|
||||
|
||||
# there should be no musicians in the response
|
||||
music_session["participants"].length.should == 0
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue