asterisk-ari 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +20 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +38 -0
- data/Rakefile +8 -0
- data/asterisk-ari.gemspec +28 -0
- data/lib/ari.rb +2 -0
- data/lib/ari/client.rb +1441 -0
- data/lib/ari/errors.rb +38 -0
- data/lib/ari/http_services.rb +87 -0
- data/lib/ari/json.rb +23 -0
- data/lib/ari/response.rb +18 -0
- data/lib/ari/version.rb +3 -0
- data/spec/ari/client_spec.rb +158 -0
- data/spec/ari/errors_spec.rb +25 -0
- data/spec/ari/http_service_spec.rb +18 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_applications_list_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_asterisk_get_info_returns_data.yml +39 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_bridges_create_returns_data.yml +147 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_bridges_list_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_channels_list_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_device_states_list_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_endpoints_list_by_tech_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_endpoints_list_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_endpoints_send_message_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_global_var_asterisk_set_global_var_and_asterisk_get_global_var_returns_data.yml +73 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_recordings_list_stored_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_sounds_get_returns_data.yml +38 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_sounds_list_with_params_returns_data.yml +395 -0
- data/spec/fixtures/vcr_cassettes/ARI_Client/api_request_sounds_list_without_params_returns_data.yml +395 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/config.yml +4 -0
- data/spec/support/config_loader.rb +2 -0
- data/spec/support/vcr.rb +14 -0
- metadata +164 -0
data/lib/ari/errors.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module ARI
|
2
|
+
|
3
|
+
class ARIError < StandardError; end
|
4
|
+
|
5
|
+
class Error < ARIError
|
6
|
+
attr_accessor :error_info, :response_body
|
7
|
+
|
8
|
+
def initialize(response_body = "", error_info = nil)
|
9
|
+
if response_body && response_body.is_a?(String)
|
10
|
+
@response_body = response_body.strip
|
11
|
+
else
|
12
|
+
@response_body = ''
|
13
|
+
end
|
14
|
+
if error_info.nil?
|
15
|
+
begin
|
16
|
+
error_info = ARI::JSON.load(response_body.to_s)
|
17
|
+
rescue
|
18
|
+
error_info ||= {}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@error_info = error_info
|
22
|
+
message = @response_body
|
23
|
+
super(message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# handle 5xx response
|
28
|
+
class ServerError < Error
|
29
|
+
def initialize(response_body, error_info)
|
30
|
+
@response_body = response_body
|
31
|
+
@error_info = error_info
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# handle 4xx response
|
36
|
+
class APIError < Error; end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "ari/json"
|
2
|
+
require "ari/response"
|
3
|
+
require "cgi"
|
4
|
+
|
5
|
+
module ARI
|
6
|
+
module HTTPService
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
def self.server(options = {})
|
11
|
+
options[:host]
|
12
|
+
end
|
13
|
+
end# end class_eval
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module NetHTTPService
|
18
|
+
require "net/http" unless defined?(Net::HTTP)
|
19
|
+
require "net/https"
|
20
|
+
|
21
|
+
METHODS = {
|
22
|
+
:get => Net::HTTP::Get,
|
23
|
+
:post => Net::HTTP::Post,
|
24
|
+
:put => Net::HTTP::Put,
|
25
|
+
:delete => Net::HTTP::Delete
|
26
|
+
}
|
27
|
+
|
28
|
+
def self.included(base)
|
29
|
+
base.class_eval do
|
30
|
+
|
31
|
+
include ARI::HTTPService
|
32
|
+
|
33
|
+
def self.make_request(path, args, verb, options = {})
|
34
|
+
args.merge!({:method => verb})
|
35
|
+
|
36
|
+
http = create_http(server(options), options)
|
37
|
+
http.use_ssl = true if options[:port].to_i == 443
|
38
|
+
|
39
|
+
result = http.start do |http|
|
40
|
+
request = case verb.to_sym
|
41
|
+
when :get
|
42
|
+
METHODS[verb.to_sym].new "#{path}?#{encode_params(args)}"
|
43
|
+
else
|
44
|
+
request = METHODS[verb.to_sym].new path
|
45
|
+
request.set_form_data args
|
46
|
+
request
|
47
|
+
end
|
48
|
+
# basic auth
|
49
|
+
if options[:username] && options[:password]
|
50
|
+
request.basic_auth(options[:username], options[:password])
|
51
|
+
end
|
52
|
+
response, body = http.request(request)
|
53
|
+
ARI::Response.new(response.code.to_i, response.body, response)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def self.encode_params(param_hash)
|
60
|
+
((param_hash || {}).collect do |key_and_value|
|
61
|
+
key_and_value[1] = ARI::JSON.dump(key_and_value[1]) if key_and_value[1].class != String
|
62
|
+
"#{key_and_value[0].to_s}=#{CGI.escape key_and_value[1]}"
|
63
|
+
end).join("&")
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.create_http(server, options)
|
67
|
+
if options[:proxy]
|
68
|
+
proxy = URI.parse(options[:proxy])
|
69
|
+
http = Net::HTTP.new \
|
70
|
+
server, options[:port],
|
71
|
+
proxy.host, proxy.port,
|
72
|
+
proxy.user, proxy.password
|
73
|
+
else
|
74
|
+
http = Net::HTTP.new server, options[:port]
|
75
|
+
end
|
76
|
+
if options[:timeout]
|
77
|
+
http.open_timeout = options[:timeout]
|
78
|
+
http.read_timeout = options[:timeout]
|
79
|
+
end
|
80
|
+
http
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
data/lib/ari/json.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "multi_json"
|
2
|
+
|
3
|
+
module ARI
|
4
|
+
module JSON
|
5
|
+
|
6
|
+
def self.dump(*args)
|
7
|
+
if MultiJson.respond_to?(:dump)
|
8
|
+
MultiJson.dump(*args)
|
9
|
+
else
|
10
|
+
MultiJson.encode(*args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.load(*args)
|
15
|
+
if MultiJson.respond_to?(:load)
|
16
|
+
MultiJson.load(*args)
|
17
|
+
else
|
18
|
+
MultiJson.decode(*args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/ari/response.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module ARI
|
2
|
+
# @!attribute [r] status
|
3
|
+
# @return [Integer] http status
|
4
|
+
# @!attribute [r] body
|
5
|
+
# @return [String] response body
|
6
|
+
# @!attribute [r] headers
|
7
|
+
# @return [String] response headers
|
8
|
+
class Response
|
9
|
+
|
10
|
+
def initialize(status, body, headers)
|
11
|
+
@status = status
|
12
|
+
@body = body
|
13
|
+
@headers = headers
|
14
|
+
end
|
15
|
+
attr_reader :status, :body, :headers
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/ari/version.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ARI::Client do
|
4
|
+
before(:each) do
|
5
|
+
@client ||= ARI::Client.new({
|
6
|
+
:host => SPEC_CONF["host"],
|
7
|
+
:port => SPEC_CONF["port"],
|
8
|
+
:username => SPEC_CONF["username"],
|
9
|
+
:password => SPEC_CONF["password"]
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has an attr_reader for host" do
|
14
|
+
@client.host.should == SPEC_CONF["host"]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has an attr_reader for port" do
|
18
|
+
@client.port.should == SPEC_CONF["port"]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has an attr_reader for username" do
|
22
|
+
@client.username.should == SPEC_CONF["username"]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has an attr_reader for password" do
|
26
|
+
@client.password.should == SPEC_CONF["password"]
|
27
|
+
end
|
28
|
+
|
29
|
+
context "api request", :vcr do
|
30
|
+
describe "#asterisk_get_info" do
|
31
|
+
it "returns data" do
|
32
|
+
result = @client.asterisk_get_info
|
33
|
+
result["build"].nil?.should == false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context "global_var" do
|
37
|
+
describe "#asterisk_set_global_var and #asterisk_get_global_var" do
|
38
|
+
it "returns data" do
|
39
|
+
key = "FOO"
|
40
|
+
value = "BAR"
|
41
|
+
result = @client.asterisk_set_global_var({:variable => key, :value => value})
|
42
|
+
result.should == ""
|
43
|
+
result = @client.asterisk_get_global_var({:variable => key})
|
44
|
+
result["value"].should == value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#bridges_list" do
|
50
|
+
it "returns data" do
|
51
|
+
result = @client.bridges_list
|
52
|
+
result.is_a?(Array).should == true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#bridges_create" do
|
57
|
+
it "returns data" do
|
58
|
+
bridge_id = "1409571774"
|
59
|
+
bridge_name = "bridge_name"
|
60
|
+
bridge_type = "mixing"
|
61
|
+
result = @client.bridges_create({:type => "mixing", :bridgeId => bridge_id, :name => bridge_name})
|
62
|
+
result["bridge_type"].should == bridge_type
|
63
|
+
result["id"].should == bridge_id
|
64
|
+
result["name"].should == bridge_name
|
65
|
+
|
66
|
+
new_bridge_type = "holding"
|
67
|
+
result = @client.bridges_create_or_update_with_id(bridge_id, {:type => new_bridge_type})
|
68
|
+
result["bridge_type"].should == new_bridge_type
|
69
|
+
result["id"].should == bridge_id
|
70
|
+
# result["name"].should == bridge_name
|
71
|
+
|
72
|
+
result = @client.bridges_get(bridge_id)
|
73
|
+
result["bridge_type"].should == new_bridge_type
|
74
|
+
result["id"].should == bridge_id
|
75
|
+
# result["name"].should == bridge_name
|
76
|
+
|
77
|
+
result = @client.bridges_destroy(bridge_id)
|
78
|
+
result.should == ""
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#channels_list" do
|
83
|
+
it "returns data" do
|
84
|
+
result = @client.channels_list
|
85
|
+
result.is_a?(Array).should == true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#endpoints_list" do
|
90
|
+
it "returns data" do
|
91
|
+
result = @client.endpoints_list
|
92
|
+
result.is_a?(Array).should == true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#endpoints_send_message" do
|
97
|
+
it "returns data" do
|
98
|
+
result = @client.endpoints_send_message({:to => "SIP", :from => "IAX2", :body => "body"})
|
99
|
+
result.should == ""
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#endpoints_list_by_tech" do
|
104
|
+
it "returns data" do
|
105
|
+
result = @client.endpoints_list_by_tech("SIP")
|
106
|
+
result.is_a?(Array).should == true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#recordings_list_stored" do
|
111
|
+
it "returns data" do
|
112
|
+
result = @client.recordings_list_stored
|
113
|
+
result.is_a?(Array).should == true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#sounds_list" do
|
118
|
+
context "without params" do
|
119
|
+
it "returns data" do
|
120
|
+
result = @client.sounds_list
|
121
|
+
result.is_a?(Array).should == true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
context "with params" do
|
125
|
+
it "returns data" do
|
126
|
+
result = @client.sounds_list({:lang => "en"})
|
127
|
+
result.is_a?(Array).should == true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#sounds_get" do
|
133
|
+
it "returns data" do
|
134
|
+
id = "vm-torerecord"
|
135
|
+
result = @client.sounds_get(id)
|
136
|
+
result["id"].should == id
|
137
|
+
result["text"].nil?.should == false
|
138
|
+
result["formats"].nil?.should == false
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#applications_list" do
|
143
|
+
it "returns data" do
|
144
|
+
result = @client.applications_list
|
145
|
+
result.is_a?(Array).should == true
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "#device_states_list" do
|
150
|
+
it "returns data" do
|
151
|
+
result = @client.device_states_list
|
152
|
+
result.is_a?(Array).should == true
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ARI::Error do
|
4
|
+
it "is a ARI::ARIError" do
|
5
|
+
ARI::Error.new(nil, nil).should be_a(ARI::ARIError)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ARI::ARIError do
|
10
|
+
it "is a StandardError" do
|
11
|
+
ARI::ARIError.new.should be_a(StandardError)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ARI::APIError do
|
16
|
+
it "is a ARI::APIError" do
|
17
|
+
ARI::APIError.new({}).should be_a(ARI::APIError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ARI::ServerError do
|
22
|
+
it "is a ARI::Error" do
|
23
|
+
ARI::ServerError.new(nil, nil).should be_a(ARI::ServerError)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class FakeHTTPService
|
4
|
+
include ARI::HTTPService
|
5
|
+
end
|
6
|
+
|
7
|
+
describe ARI::HTTPService do
|
8
|
+
|
9
|
+
describe "common methods" do
|
10
|
+
describe "server" do
|
11
|
+
it "should return the host" do
|
12
|
+
FakeHTTPService.server(:host => SPEC_CONF["host"]).should == SPEC_CONF["host"]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://asterisk:asterisk@127.0.0.1:8088/ari/applications?method=get
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept-Encoding:
|
11
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
12
|
+
Accept:
|
13
|
+
- "*/*"
|
14
|
+
User-Agent:
|
15
|
+
- Ruby
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Server:
|
22
|
+
- Asterisk/12.5.0
|
23
|
+
Date:
|
24
|
+
- Mon, 01 Sep 2014 13:36:13 GMT
|
25
|
+
Connection:
|
26
|
+
- close
|
27
|
+
Cache-Control:
|
28
|
+
- no-cache, no-store
|
29
|
+
Content-Type:
|
30
|
+
- application/json
|
31
|
+
Content-Length:
|
32
|
+
- '2'
|
33
|
+
body:
|
34
|
+
encoding: UTF-8
|
35
|
+
string: "[]"
|
36
|
+
http_version:
|
37
|
+
recorded_at: Mon, 01 Sep 2014 13:36:13 GMT
|
38
|
+
recorded_with: VCR 2.9.2
|
@@ -0,0 +1,39 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://asterisk:asterisk@127.0.0.1:8088/ari/asterisk/info?method=get
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept-Encoding:
|
11
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
12
|
+
Accept:
|
13
|
+
- "*/*"
|
14
|
+
User-Agent:
|
15
|
+
- Ruby
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Server:
|
22
|
+
- Asterisk/12.5.0
|
23
|
+
Date:
|
24
|
+
- Mon, 01 Sep 2014 11:11:42 GMT
|
25
|
+
Connection:
|
26
|
+
- close
|
27
|
+
Cache-Control:
|
28
|
+
- no-cache, no-store
|
29
|
+
Content-Type:
|
30
|
+
- application/json
|
31
|
+
Content-Length:
|
32
|
+
- '419'
|
33
|
+
body:
|
34
|
+
encoding: UTF-8
|
35
|
+
string: '{"config":{"default_language":"en","name":"","setid":{"group":"","user":""}},"build":{"os":"Linux","kernel":"3.13.0-34-generic","machine":"x86_64","user":"tk","options":"LOADABLE_MODULES,
|
36
|
+
BUILD_NATIVE, OPTIONAL_API","date":"2014-09-01 10:40:07 UTC"},"system":{"entity_id":"08:00:27:51:53:a7","version":"12.5.0"},"status":{"startup_time":"2014-09-01T20:10:30.620+0900","last_reload_time":"2014-09-01T20:10:30.620+0900"}}'
|
37
|
+
http_version:
|
38
|
+
recorded_at: Mon, 01 Sep 2014 11:11:42 GMT
|
39
|
+
recorded_with: VCR 2.9.2
|