punchblock 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Guardfile +1 -1
- data/lib/punchblock/client.rb +2 -2
- data/lib/punchblock/client/component_registry.rb +5 -5
- data/lib/punchblock/component/component_node.rb +1 -0
- data/lib/punchblock/component/input.rb +2 -2
- data/lib/punchblock/core_ext/blather/stanza.rb +1 -1
- data/lib/punchblock/rayo_node.rb +4 -2
- data/lib/punchblock/translator/asterisk/call.rb +2 -2
- data/lib/punchblock/translator/asterisk/component.rb +1 -0
- data/lib/punchblock/translator/freeswitch/call.rb +1 -1
- data/lib/punchblock/translator/freeswitch/component.rb +1 -0
- data/lib/punchblock/version.rb +1 -1
- data/punchblock.gemspec +1 -1
- data/spec/punchblock/client/component_registry_spec.rb +5 -5
- data/spec/punchblock/client_spec.rb +3 -2
- data/spec/punchblock/component/component_node_spec.rb +7 -6
- data/spec/punchblock/connection/xmpp_spec.rb +1 -0
- data/spec/punchblock/translator/asterisk/call_spec.rb +37 -19
- data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +1 -1
- data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +2 -0
- data/spec/punchblock/translator/asterisk/component_spec.rb +1 -1
- data/spec/punchblock/translator/freeswitch/call_spec.rb +2 -1
- data/spec/punchblock/translator/freeswitch/component_spec.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8dddb3e5a8b1158136add6d851f6f40fbe94438
|
4
|
+
data.tar.gz: ff999c1ed2536e739167e74ab6d9ac96c188f0e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8817401f7029230cc46119a8fabe2a525b72c0af9375eb09127dfbbf8855617ac1a553b2fca2699accec6311df9d9bb378a6dff5322a9df0b26e6a994d2f66fb
|
7
|
+
data.tar.gz: 43668278a0c3943259fbbc75f4b0704e6cc617d41fb2f405b3b0fac1d6aa8093ea78bbf24a8c868b55b3ccced90da00648af8d3b5a18163cecb074dd1b845510
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# [develop](https://github.com/adhearsion/punchblock)
|
2
2
|
|
3
|
+
# [v2.0.2](https://github.com/adhearsion/punchblock/compare/v2.0.1...v2.0.2) - [2013-10-17](https://rubygems.org/gems/punchblock/versions/2.0.2)
|
4
|
+
* Bugfix: Reject commands against components which have finished on Asterisk, and garbage collect them
|
5
|
+
* Bugfix: Register/lookup components by their full URI rather than component ID since the component ID may only be unique per call
|
6
|
+
* Bugfix: Hold back Virtus dependency to avoid API-breaking changes
|
7
|
+
|
3
8
|
# [v2.0.1](https://github.com/adhearsion/punchblock/compare/v2.0.0...v2.0.1) - [2013-09-17](https://rubygems.org/gems/punchblock/versions/2.0.1)
|
4
9
|
* Bugfix: Allow audio file URIs with file extensions on Asterisk
|
5
10
|
* Bugfix: Input timers were being started before output finished on Asterisk composed prompts
|
data/Guardfile
CHANGED
data/lib/punchblock/client.rb
CHANGED
@@ -38,8 +38,8 @@ module Punchblock
|
|
38
38
|
component_registry << component
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
component_registry.
|
41
|
+
def find_component_by_uri(uri)
|
42
|
+
component_registry.find_by_uri uri
|
43
43
|
end
|
44
44
|
|
45
45
|
def delete_component_registration(component)
|
@@ -10,20 +10,20 @@ module Punchblock
|
|
10
10
|
|
11
11
|
def <<(component)
|
12
12
|
@mutex.synchronize do
|
13
|
-
@components[component.
|
13
|
+
@components[component.source_uri] = component
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def find_by_uri(uri)
|
18
18
|
@mutex.synchronize do
|
19
|
-
@components[
|
19
|
+
@components[uri]
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def delete(component)
|
24
24
|
@mutex.synchronize do
|
25
|
-
|
26
|
-
@components.delete
|
25
|
+
uri = @components.key component
|
26
|
+
@components.delete uri
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -28,10 +28,10 @@ module Punchblock
|
|
28
28
|
# @return [Float] Indicates how sensitive the interpreter should be to loud versus quiet input. Higher values represent greater sensitivity.
|
29
29
|
attribute :sensitivity, Float
|
30
30
|
|
31
|
-
# @return [Integer] Indicates the amount of time preceding input which may expire before a timeout is triggered.
|
31
|
+
# @return [Integer] Indicates the amount of time (in milliseconds) preceding input which may expire before a timeout is triggered.
|
32
32
|
attribute :initial_timeout, Integer
|
33
33
|
|
34
|
-
# @return [Integer] Indicates (in the case of DTMF input) the amount of time between input digits which may expire before a timeout is triggered.
|
34
|
+
# @return [Integer] Indicates (in the case of DTMF input) the amount of time (in milliseconds) between input digits which may expire before a timeout is triggered.
|
35
35
|
attribute :inter_digit_timeout, Integer
|
36
36
|
|
37
37
|
attribute :grammars, Array, default: []
|
@@ -10,7 +10,7 @@ module Blather
|
|
10
10
|
def rayo_node
|
11
11
|
@rayo_node ||= begin
|
12
12
|
first_child = at_xpath RAYO_NODE_PATH, Punchblock::RAYO_NAMESPACES
|
13
|
-
Punchblock::RayoNode.from_xml first_child, nil, component_id if first_child
|
13
|
+
Punchblock::RayoNode.from_xml first_child, nil, component_id, "xmpp:#{from}" if first_child
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
data/lib/punchblock/rayo_node.rb
CHANGED
@@ -14,6 +14,7 @@ module Punchblock
|
|
14
14
|
attribute :target_call_id
|
15
15
|
attribute :target_mixer_name
|
16
16
|
attribute :component_id
|
17
|
+
attribute :source_uri
|
17
18
|
attribute :domain
|
18
19
|
attribute :transport
|
19
20
|
|
@@ -48,7 +49,7 @@ module Punchblock
|
|
48
49
|
# elements of the XML::Node
|
49
50
|
# @param [XML::Node] node the node to import
|
50
51
|
# @return the appropriate object based on the node name and namespace
|
51
|
-
def self.from_xml(node, call_id = nil, component_id = nil)
|
52
|
+
def self.from_xml(node, call_id = nil, component_id = nil, uri = nil)
|
52
53
|
ns = (node.namespace.href if node.namespace)
|
53
54
|
klass = class_from_registration(node.name, ns)
|
54
55
|
if klass && klass != self
|
@@ -58,6 +59,7 @@ module Punchblock
|
|
58
59
|
end.tap do |event|
|
59
60
|
event.target_call_id = call_id
|
60
61
|
event.component_id = component_id
|
62
|
+
event.source_uri = uri
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
@@ -85,7 +87,7 @@ module Punchblock
|
|
85
87
|
# @return [RayoNode] the original command issued that lead to this event
|
86
88
|
#
|
87
89
|
def source
|
88
|
-
@source ||= client.
|
90
|
+
@source ||= client.find_component_by_uri source_uri if client && source_uri
|
89
91
|
@source ||= original_component
|
90
92
|
end
|
91
93
|
|
@@ -291,10 +291,10 @@ module Punchblock
|
|
291
291
|
end
|
292
292
|
|
293
293
|
def actor_died(actor, reason)
|
294
|
-
return unless reason
|
295
294
|
if id = @components.key(actor)
|
296
295
|
@components.delete id
|
297
|
-
|
296
|
+
return unless reason
|
297
|
+
complete_event = Punchblock::Event::Complete.new :component_id => id, source_uri: id, :reason => Punchblock::Event::Complete::Error.new
|
298
298
|
send_pb_event complete_event
|
299
299
|
end
|
300
300
|
end
|
@@ -236,7 +236,7 @@ module Punchblock
|
|
236
236
|
pb_logger.error "A linked actor (#{actor.inspect}) died due to #{reason.inspect}"
|
237
237
|
if id = @components.key(actor)
|
238
238
|
@components.delete id
|
239
|
-
complete_event = Punchblock::Event::Complete.new :component_id => id, :reason => Punchblock::Event::Complete::Error.new
|
239
|
+
complete_event = Punchblock::Event::Complete.new :component_id => id, source_uri: id, :reason => Punchblock::Event::Complete::Error.new
|
240
240
|
send_pb_event complete_event
|
241
241
|
end
|
242
242
|
end
|
data/lib/punchblock/version.rb
CHANGED
data/punchblock.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.add_runtime_dependency %q<ruby_ami>, ["~> 2.0"]
|
33
33
|
s.add_runtime_dependency %q<ruby_fs>, ["~> 1.1"]
|
34
34
|
s.add_runtime_dependency %q<ruby_speech>, ["~> 2.0"]
|
35
|
-
s.add_runtime_dependency %q<virtus
|
35
|
+
s.add_runtime_dependency %q<virtus>, ["~> 0.5"]
|
36
36
|
s.add_runtime_dependency %q<ruby_jid>, ["~> 1.0"]
|
37
37
|
|
38
38
|
s.add_development_dependency %q<bundler>, ["~> 1.0"]
|
@@ -5,19 +5,19 @@ require 'spec_helper'
|
|
5
5
|
module Punchblock
|
6
6
|
class Client
|
7
7
|
describe ComponentRegistry do
|
8
|
-
let(:
|
9
|
-
let(:component)
|
8
|
+
let(:uri) { 'abc123' }
|
9
|
+
let(:component) { double 'Component', source_uri: uri }
|
10
10
|
|
11
11
|
it 'should store components and allow lookup by ID' do
|
12
12
|
subject << component
|
13
|
-
subject.
|
13
|
+
subject.find_by_uri(uri).should be component
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should allow deletion of components' do
|
17
17
|
subject << component
|
18
|
-
subject.
|
18
|
+
subject.find_by_uri(uri).should be component
|
19
19
|
subject.delete component
|
20
|
-
subject.
|
20
|
+
subject.find_by_uri(uri).should be_nil
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -14,7 +14,8 @@ module Punchblock
|
|
14
14
|
let(:call_id) { 'abc123' }
|
15
15
|
let(:mock_event) { double('Event').as_null_object }
|
16
16
|
let(:component_id) { 'abc123' }
|
17
|
-
let(:
|
17
|
+
let(:component_uri) { 'callid@server/abc123' }
|
18
|
+
let(:mock_component) { double 'Component', source_uri: component_uri }
|
18
19
|
let(:mock_command) { double 'Command' }
|
19
20
|
|
20
21
|
describe '#run' do
|
@@ -77,7 +78,7 @@ module Punchblock
|
|
77
78
|
|
78
79
|
it 'should be able to register and retrieve components' do
|
79
80
|
subject.register_component mock_component
|
80
|
-
subject.
|
81
|
+
subject.find_component_by_uri(component_uri).should be mock_component
|
81
82
|
end
|
82
83
|
|
83
84
|
describe '#execute_command' do
|
@@ -71,16 +71,17 @@ module Punchblock
|
|
71
71
|
subject.client = Client.new
|
72
72
|
end
|
73
73
|
|
74
|
-
let(:
|
74
|
+
let(:uri) { 'xmpp:callid@server/abc123' }
|
75
75
|
|
76
76
|
let :ref do
|
77
|
-
Ref.new uri:
|
77
|
+
Ref.new uri: uri
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should set the component ID from the ref" do
|
81
81
|
subject.response = ref
|
82
|
-
subject.component_id.should be ==
|
83
|
-
subject.
|
82
|
+
subject.component_id.should be == 'abc123'
|
83
|
+
subject.source_uri.should be == uri
|
84
|
+
subject.client.find_component_by_uri(uri).should be subject
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
@@ -89,7 +90,7 @@ module Punchblock
|
|
89
90
|
subject.request!
|
90
91
|
subject.client = Client.new
|
91
92
|
subject.response = Ref.new uri: 'abc'
|
92
|
-
subject.client.
|
93
|
+
subject.client.find_component_by_uri('abc').should be subject
|
93
94
|
end
|
94
95
|
|
95
96
|
it "should set the command to executing status" do
|
@@ -105,7 +106,7 @@ module Punchblock
|
|
105
106
|
|
106
107
|
it "should remove the component from the registry" do
|
107
108
|
subject.complete_event = :foo
|
108
|
-
subject.client.
|
109
|
+
subject.client.find_component_by_uri('abc').should be_nil
|
109
110
|
end
|
110
111
|
end
|
111
112
|
end # ComponentNode
|
@@ -172,6 +172,7 @@ module Punchblock
|
|
172
172
|
mock_event_handler.should_receive(:call).once.with do |event|
|
173
173
|
event.should be_instance_of Event::Offer
|
174
174
|
event.target_call_id.should be == '9f00061'
|
175
|
+
event.source_uri.should be == 'xmpp:9f00061@call.rayo.net'
|
175
176
|
event.domain.should be == 'call.rayo.net'
|
176
177
|
event.transport.should be == 'xmpp'
|
177
178
|
end
|
@@ -312,7 +312,7 @@ module Punchblock
|
|
312
312
|
comp_command.request!
|
313
313
|
component = subject.execute_command comp_command
|
314
314
|
comp_command.response(0.1).should be_a Ref
|
315
|
-
expected_complete_event = Punchblock::Event::Complete.new :target_call_id => subject.id, :component_id => component.id
|
315
|
+
expected_complete_event = Punchblock::Event::Complete.new :target_call_id => subject.id, :component_id => component.id, source_uri: component.id
|
316
316
|
expected_complete_event.reason = Punchblock::Event::Complete::Hangup.new
|
317
317
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup, platform_code: cause, :target_call_id => subject.id
|
318
318
|
|
@@ -1298,7 +1298,7 @@ module Punchblock
|
|
1298
1298
|
end
|
1299
1299
|
end
|
1300
1300
|
|
1301
|
-
context "for a component which began executing but
|
1301
|
+
context "for a component which began executing but terminated" do
|
1302
1302
|
let :component_command do
|
1303
1303
|
Punchblock::Component::Asterisk::AGI::Command.new :name => 'Wait'
|
1304
1304
|
end
|
@@ -1310,6 +1310,7 @@ module Punchblock
|
|
1310
1310
|
let :expected_event do
|
1311
1311
|
Punchblock::Event::Complete.new target_call_id: subject.id,
|
1312
1312
|
component_id: comp_id,
|
1313
|
+
source_uri: comp_id,
|
1313
1314
|
reason: Punchblock::Event::Complete::Error.new
|
1314
1315
|
end
|
1315
1316
|
|
@@ -1318,35 +1319,52 @@ module Punchblock
|
|
1318
1319
|
subject.execute_command component_command
|
1319
1320
|
end
|
1320
1321
|
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
component.wrapped_object.define_singleton_method(:oops) do
|
1325
|
-
raise 'Woops, I died'
|
1326
|
-
end
|
1327
|
-
|
1328
|
-
translator.should_receive(:handle_pb_event).once.with expected_event
|
1322
|
+
context "normally" do
|
1323
|
+
it 'sends an error in response to the command' do
|
1324
|
+
component = subject.component_with_id comp_id
|
1329
1325
|
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1326
|
+
component.terminate
|
1327
|
+
sleep 0.1
|
1328
|
+
component.should_not be_alive
|
1329
|
+
subject.component_with_id(comp_id).should be_nil
|
1334
1330
|
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1331
|
+
subsequent_command.request!
|
1332
|
+
subject.execute_command subsequent_command
|
1333
|
+
subsequent_command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id)
|
1334
|
+
end
|
1338
1335
|
end
|
1339
1336
|
|
1340
|
-
context "
|
1337
|
+
context "by crashing" do
|
1341
1338
|
it 'sends an error in response to the command' do
|
1342
1339
|
component = subject.component_with_id comp_id
|
1343
1340
|
|
1344
|
-
component.
|
1341
|
+
component.wrapped_object.define_singleton_method(:oops) do
|
1342
|
+
raise 'Woops, I died'
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
translator.should_receive(:handle_pb_event).once.with expected_event
|
1346
|
+
|
1347
|
+
lambda { component.oops }.should raise_error(/Woops, I died/)
|
1348
|
+
sleep 0.1
|
1349
|
+
component.should_not be_alive
|
1350
|
+
subject.component_with_id(comp_id).should be_nil
|
1345
1351
|
|
1346
1352
|
subsequent_command.request!
|
1347
1353
|
subject.execute_command subsequent_command
|
1348
1354
|
subsequent_command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id)
|
1349
1355
|
end
|
1356
|
+
|
1357
|
+
context "when we dispatch the command to it" do
|
1358
|
+
it 'sends an error in response to the command' do
|
1359
|
+
component = subject.component_with_id comp_id
|
1360
|
+
|
1361
|
+
component.should_receive(:execute_command).and_raise(Celluloid::DeadActorError)
|
1362
|
+
|
1363
|
+
subsequent_command.request!
|
1364
|
+
subject.execute_command subsequent_command
|
1365
|
+
subsequent_command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id)
|
1366
|
+
end
|
1367
|
+
end
|
1350
1368
|
end
|
1351
1369
|
end
|
1352
1370
|
|
@@ -90,7 +90,7 @@ module Punchblock
|
|
90
90
|
end
|
91
91
|
|
92
92
|
let :event_node do
|
93
|
-
Punchblock::Event::Asterisk::AMI::Event.new name: 'CoreShowChannel', component_id: subject.id, headers: {
|
93
|
+
Punchblock::Event::Asterisk::AMI::Event.new name: 'CoreShowChannel', component_id: subject.id, source_uri: subject.id, headers: {
|
94
94
|
'Channel' => 'SIP/127.0.0.1-00000013',
|
95
95
|
'UniqueID' => '1287686437.19',
|
96
96
|
'Context' => 'adhearsion',
|
@@ -155,6 +155,7 @@ module Punchblock
|
|
155
155
|
let :expected_event do
|
156
156
|
Punchblock::Event::Complete.new reason: expected_reason,
|
157
157
|
component_id: subject.id,
|
158
|
+
source_uri: subject.id,
|
158
159
|
target_call_id: call.id
|
159
160
|
end
|
160
161
|
|
@@ -215,6 +216,7 @@ module Punchblock
|
|
215
216
|
expected_reason = Punchblock::Event::Complete::Stop.new
|
216
217
|
expected_event = Punchblock::Event::Complete.new reason: expected_reason,
|
217
218
|
component_id: subject.id,
|
219
|
+
source_uri: subject.id,
|
218
220
|
target_call_id: call.id
|
219
221
|
|
220
222
|
call.async.should_receive(:redirect_back)
|
@@ -358,7 +358,7 @@ module Punchblock
|
|
358
358
|
component = subject.execute_command comp_command
|
359
359
|
comp_command.response(0.1).should be_a Ref
|
360
360
|
|
361
|
-
expected_complete_event = Punchblock::Event::Complete.new :target_call_id => subject.id, :component_id => component.id
|
361
|
+
expected_complete_event = Punchblock::Event::Complete.new :target_call_id => subject.id, :component_id => component.id, source_uri: component.id
|
362
362
|
expected_complete_event.reason = Punchblock::Event::Complete::Hangup.new
|
363
363
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup, :target_call_id => subject.id
|
364
364
|
|
@@ -886,6 +886,7 @@ module Punchblock
|
|
886
886
|
let :expected_event do
|
887
887
|
Punchblock::Event::Complete.new target_call_id: subject.id,
|
888
888
|
component_id: comp_id,
|
889
|
+
source_uri: comp_id,
|
889
890
|
reason: Punchblock::Event::Complete::Error.new
|
890
891
|
end
|
891
892
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: punchblock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Goecke
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-10-17 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: nokogiri
|
@@ -168,16 +168,16 @@ dependencies:
|
|
168
168
|
name: virtus
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- -
|
171
|
+
- - ~>
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
173
|
+
version: '0.5'
|
174
174
|
type: :runtime
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- -
|
178
|
+
- - ~>
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
180
|
+
version: '0.5'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: ruby_jid
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|