adhearsion 3.0.0.beta1 → 3.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.lgtm +3 -0
  3. data/.travis.yml +4 -1
  4. data/CHANGELOG.md +10 -0
  5. data/MAINTAINERS +2 -0
  6. data/README.markdown +1 -1
  7. data/adhearsion.gemspec +4 -3
  8. data/features/cli_create.feature +6 -0
  9. data/features/cli_plugin.feature +1 -1
  10. data/lib/adhearsion.rb +0 -4
  11. data/lib/adhearsion/application.rb +5 -0
  12. data/lib/adhearsion/call.rb +7 -1
  13. data/lib/adhearsion/call_controller.rb +16 -6
  14. data/lib/adhearsion/call_controller/dial.rb +2 -2
  15. data/lib/adhearsion/call_controller/input/result.rb +1 -1
  16. data/lib/adhearsion/configuration.rb +6 -25
  17. data/lib/adhearsion/events.rb +13 -3
  18. data/lib/adhearsion/generators/app/templates/adhearsion.erb +2 -2
  19. data/lib/adhearsion/generators/app/templates/config/app.rb +17 -0
  20. data/lib/adhearsion/initializer.rb +7 -0
  21. data/lib/adhearsion/plugin.rb +2 -0
  22. data/lib/adhearsion/rayo/initializer.rb +1 -0
  23. data/lib/adhearsion/router/route.rb +1 -1
  24. data/lib/adhearsion/translator/asterisk.rb +6 -2
  25. data/lib/adhearsion/translator/asterisk/call.rb +2 -1
  26. data/lib/adhearsion/translator/asterisk/component.rb +1 -0
  27. data/lib/adhearsion/translator/asterisk/component/stop_by_redirect.rb +1 -1
  28. data/lib/adhearsion/version.rb +1 -1
  29. data/spec/adhearsion/call_controller_spec.rb +32 -28
  30. data/spec/adhearsion/call_spec.rb +3 -0
  31. data/spec/adhearsion/configuration_spec.rb +16 -41
  32. data/spec/adhearsion/rayo/initializer_spec.rb +6 -0
  33. data/spec/adhearsion/translator/asterisk/call_spec.rb +56 -11
  34. data/spec/adhearsion/translator/asterisk/component/stop_by_redirect_spec.rb +1 -1
  35. data/spec/adhearsion/translator/asterisk/component_spec.rb +9 -0
  36. data/spec/adhearsion_spec.rb +0 -7
  37. data/spec/spec_helper.rb +1 -1
  38. metadata +26 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d7c56e8ead6437f2554eea0fba508eaea1971133
4
- data.tar.gz: 00795ee77e30cfb4ec49e5214c6a84cd82ac164f
3
+ metadata.gz: b3cc409522daab633c1bc664407fdfc6a5108694
4
+ data.tar.gz: 5c9a537a64f4a571916f1fd90bce584b9ea4ab95
5
5
  SHA512:
6
- metadata.gz: 65d347d4f9141f0e99643c69b8df7e0d2008ca6ac51fa936641ffa27b9e848defe7435f45482593b12b21020677fa46707b4b4b9a259ee02d27c6d78d8b21944
7
- data.tar.gz: fd7ae40b068100dfeab3b2ddc5aa22cec816076bb30ac719800eddd8b558fa227b401e1cb7f47c00c5054eb25a1f6593624759ba747bdbca78434e3029be4033
6
+ metadata.gz: 5a1567863c4da74228af44de62df55dc68cc4d2dca383e9c3719b7d079131035462c42a8687b956459115f514a59edf6a5affd7059c34a3199aaa1a856538a3d
7
+ data.tar.gz: 2de7f4d8e52804198127af271104a7c52335c67a4bf3a20b613a3bef858afd6b4bb9d6b2135ef267c535d77701ad09e2c0968fe12036c80de24b83f72d4f5275
data/.lgtm ADDED
@@ -0,0 +1,3 @@
1
+ approvals = 1
2
+ pattern = "(?i):shipit:|:\\+1:|LGTM"
3
+
@@ -3,7 +3,7 @@ rvm:
3
3
  - 2.2.0
4
4
  - 2.2.1
5
5
  - 2.2.2
6
- - jruby-9.0.0.0.pre2
6
+ - jruby-9.0.0.0
7
7
  - ruby-head
8
8
  jdk:
9
9
  - openjdk7 # for jruby
@@ -13,3 +13,6 @@ matrix:
13
13
  - rvm: ruby-head
14
14
  env: ARUBA_TIMEOUT=120 AHN_ENV=development
15
15
  sudo: false
16
+ notifications:
17
+ slack:
18
+ secure: Y7EqF/9FY7mca63c1DM7kEr34fNtFclWXJj9vLqVQJwR3rCDZUZSD8DlqHJDwE6KRCCDsSkyV4lihCim+GEM28CRcJir0AEUJhXHvIMckjH7n38W9OGN26RuJGZTapjgCSMOBeq0YpSe6dAnZeRpZRJxsTFtP5ptLD5RRjIMzZM=
@@ -1,5 +1,14 @@
1
1
  # [develop](https://github.com/adhearsion/adhearsion)
2
2
 
3
+ # [3.0.0.beta2](https://github.com/adhearsion/adhearsion/compare/v3.0.0.beta1...v3.0.0.beta2) - [2015-12-18](https://rubygems.org/gems/adhearsion/versions/3.0.0.beta2)
4
+ * Bugfix: Ensure components are deregistered from asterisk translator once the call is ended ([#582](https://github.com/adhearsion/adhearsion/pull/582))
5
+ * Change: Define configuration per-environment for any environment name and without colliding with plugin names. See [#442](https://github.com/adhearsion/adhearsion/issues/442). Syntax is now `config.env(:development).foo = :bar` instead of `config.development.foo = :bar`.
6
+ * Feature: Introduce the concept of application specific config. Similar to a plugin, an Application can specify config and an initialiser, and is the place to put such application-wide and unshareable things.
7
+ * Bugfix: Calls remain inactive even after they shut down. Previously, to reliably check if a call was up or down it was necessary to consider the case where the call actor had been shut down. This is irrelevant to the `Adhearsion::Call#active?` question, which should *always* return a boolean. It now does.
8
+ * Bugfix: Process joined events on Asterisk 13 in any order, avoiding Join command timeout
9
+ * Bugfix: Handle correct event for confirming that a component stop was completed on Asterisk 13
10
+ * Bugfix: Avoid race conditions in processing calls with interactions between them
11
+
3
12
  # [3.0.0.beta1](https://github.com/adhearsion/adhearsion/compare/v2.6.1...v3.0.0.beta1) - [2015-06-24](https://rubygems.org/gems/adhearsion/versions/3.0.0.beta1)
4
13
  * Change: Removed `Adhearsion.ahn_root=` which was deprecated in favour of `Adhearsion.root=`
5
14
  * Change: Remove integration with `RAILS_ENV`
@@ -18,6 +27,7 @@
18
27
  * Change: Ruby 1.9 is no longer supported. Minimum supported versions are Ruby 2.2.0 and JRuby 9.0.0.0
19
28
  * Change: Rename "platform" to "core" relating to the config system, because "platform" is overloaded. Settings are now `config.core.*` or `AHN_CORE_*`.
20
29
  * Change: Permit application environment to be set only by AHN_ENV. The config system depends on the environment, and the previous dependency was circular.
30
+ * Change: Define configuration per-environment for any environment name and without colliding with plugin names. See [#442](https://github.com/adhearsion/adhearsion/issues/442). Syntax is now `config.env(:development).foo = :bar` instead of `config.development.foo = :bar`.
21
31
  * Feature: Add i18n support via `CallController#t`
22
32
  * Feature: Integrate a Rack-based HTTP server from the Virginia plugin
23
33
  * Feature: Permit timing out when calling `Call#wait_for_end`
@@ -0,0 +1,2 @@
1
+ Ben Langfeld <ben@langfeld.me> (@benlangfeld)
2
+ Ben Klang <bklang@mojolingo.com> (@bklang)
@@ -28,7 +28,7 @@ Adhearsion rests above a lower-level telephony platform, for example [Asterisk](
28
28
  * [ruby_speech dependencies](https://github.com/benlangfeld/ruby_speech#dependencies)
29
29
  * A VoIP platform:
30
30
  * Asterisk 11+
31
- * A Rayo server (Prism 11+ with rayo-server, or FreeSWITCH with mod_rayo)
31
+ * FreeSWITCH 1.4+
32
32
  * An interest in building cool new things
33
33
 
34
34
  **Ruby 1.9 is no longer supported by Adhearsion or the Ruby core team. You should upgrade to Ruby 2.2 as a matter of urgency in order to continue receiving security fixes.**
@@ -25,14 +25,15 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency 'adhearsion-loquacious', ["~> 1.9"]
26
26
  s.add_runtime_dependency 'blather', ["~> 1.0"]
27
27
  s.add_runtime_dependency 'bundler', ["~> 1.0"]
28
- s.add_runtime_dependency 'celluloid', ["~> 0.16"]
28
+ s.add_runtime_dependency 'celluloid', ["~> 0.16.0"]
29
29
  s.add_runtime_dependency 'countdownlatch'
30
30
  s.add_runtime_dependency 'deep_merge'
31
31
  s.add_runtime_dependency 'ffi', ["~> 1.0"]
32
32
  s.add_runtime_dependency 'future-resource', ["~> 1.0"]
33
33
  s.add_runtime_dependency 'has-guarded-handlers', ["~> 1.6", ">= 1.6.3"]
34
+ s.add_runtime_dependency 'http', ["~> 0.9.8"] # Pin back so Reel doesn't break
34
35
  s.add_runtime_dependency 'i18n', ["~> 0.6"]
35
- s.add_runtime_dependency 'logging', ["~> 1.8"]
36
+ s.add_runtime_dependency 'logging', ["~> 2.0"]
36
37
  s.add_runtime_dependency 'nokogiri', ["~> 1.5", ">= 1.5.6"]
37
38
  s.add_runtime_dependency 'pry'
38
39
  s.add_runtime_dependency 'rake'
@@ -45,7 +46,7 @@ Gem::Specification.new do |s|
45
46
  s.add_runtime_dependency 'thor', "~> 0.18.0"
46
47
  s.add_runtime_dependency 'virtus', ["~> 1.0"]
47
48
 
48
- s.add_development_dependency 'aruba', "~> 0.5"
49
+ s.add_development_dependency 'aruba', "~> 0.6.0"
49
50
  s.add_development_dependency 'ci_reporter_rspec'
50
51
  s.add_development_dependency 'ci_reporter_cucumber'
51
52
  s.add_development_dependency 'cucumber'
@@ -24,6 +24,7 @@ Feature: Adhearsion Ahn CLI (Create)
24
24
  | app/assets/audio/en/hello_world.wav |
25
25
  | app/call_controllers/simon_game.rb |
26
26
  | config/adhearsion.rb |
27
+ | config/app.rb |
27
28
  | config/environment.rb |
28
29
  | config/events.rb |
29
30
  | config/routes.rb |
@@ -43,6 +44,10 @@ Feature: Adhearsion Ahn CLI (Create)
43
44
  logging.level
44
45
  config.core.username
45
46
  """
47
+ And the file "config/app.rb" should contain each of these content parts:
48
+ """
49
+ config do
50
+ """
46
51
  And the file "config/events.rb" should contain each of these content parts:
47
52
  """
48
53
  Adhearsion::Events.draw do
@@ -88,6 +93,7 @@ Feature: Adhearsion Ahn CLI (Create)
88
93
  | .gitignore |
89
94
  | .rspec |
90
95
  | config/adhearsion.rb |
96
+ | config/app.rb |
91
97
  | config/environment.rb |
92
98
  | config/events.rb |
93
99
  | config/routes.rb |
@@ -27,7 +27,7 @@ Feature: Adhearsion Ahn CLI (Plugin)
27
27
  And I type "SECRET_CODE"
28
28
  Then the output should contain:
29
29
  """
30
- Access Denied. Please sign up for an account at http://rubygems.org
30
+ Access Denied.
31
31
  """
32
32
 
33
33
  Scenario: Command create_github_hook
@@ -47,10 +47,6 @@ module Adhearsion
47
47
  @environment = other ? other.to_sym : other
48
48
  end
49
49
 
50
- def environments
51
- config.valid_environments
52
- end
53
-
54
50
  def config=(config)
55
51
  @config = config
56
52
  end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ require 'adhearsion/plugin'
4
+
5
+ Adhearsion::Application = Adhearsion::Plugin
@@ -23,6 +23,12 @@ module Adhearsion
23
23
  rescue ::Celluloid::DeadActorError
24
24
  raise ExpiredError, "This call is expired and is no longer accessible. See http://adhearsion.com/docs/calls for further details."
25
25
  end
26
+
27
+ def active?
28
+ alive? && super
29
+ rescue ExpiredError
30
+ false
31
+ end
26
32
  end
27
33
 
28
34
  include Celluloid
@@ -535,7 +541,7 @@ module Adhearsion
535
541
  def execute_controller(controller = nil, completion_callback = nil, &block)
536
542
  raise ArgumentError, "Cannot supply a controller and a block at the same time" if controller && block_given?
537
543
  controller ||= CallController.new current_actor, &block
538
- logger.info "Executing controller #{controller.inspect}"
544
+ logger.info "Executing controller #{controller.class}"
539
545
  controller.bg_exec completion_callback
540
546
  end
541
547
 
@@ -18,7 +18,7 @@ module Adhearsion
18
18
 
19
19
  class_attribute :callbacks
20
20
 
21
- self.callbacks = {:before_call => [], :after_call => [], :on_error => []}
21
+ self.callbacks = {:before => [], :after => [], :on_error => []}
22
22
 
23
23
  self.callbacks.keys.each do |name|
24
24
  class_eval <<-STOP
@@ -49,6 +49,16 @@ module Adhearsion
49
49
  def mixin(mod)
50
50
  include mod
51
51
  end
52
+
53
+ def before_call(*args, &block)
54
+ Adhearsion.deprecated :before
55
+ before(*args, &block)
56
+ end
57
+
58
+ def after_call(*args, &block)
59
+ Adhearsion.deprecated :after
60
+ after(*args, &block)
61
+ end
52
62
  end
53
63
 
54
64
  # @return [Call] The call object on which the controller is executing
@@ -113,7 +123,7 @@ module Adhearsion
113
123
  # @private
114
124
  def execute!(*options)
115
125
  call.async.register_controller self
116
- execute_callbacks :before_call
126
+ execute_callbacks :before
117
127
  run
118
128
  rescue Call::Hangup, Call::ExpiredError
119
129
  rescue SyntaxError, StandardError => e
@@ -121,7 +131,7 @@ module Adhearsion
121
131
  on_error e
122
132
  raise
123
133
  ensure
124
- after_call
134
+ after
125
135
  logger.debug "Finished executing controller #{self.inspect}"
126
136
  end
127
137
 
@@ -189,8 +199,8 @@ module Adhearsion
189
199
  end
190
200
 
191
201
  # @private
192
- def after_call
193
- @after_call ||= execute_callbacks :after_call
202
+ def after
203
+ @after ||= execute_callbacks :after
194
204
  end
195
205
 
196
206
  # @private
@@ -234,7 +244,7 @@ module Adhearsion
234
244
  end
235
245
 
236
246
  #
237
- # Hangup the call, and execute after_call callbacks
247
+ # Hangup the call, and execute after callbacks
238
248
  #
239
249
  # @param [Hash] headers
240
250
  #
@@ -74,7 +74,7 @@ module Adhearsion
74
74
  attr_accessor :status
75
75
 
76
76
  def initialize(to, options, call)
77
- raise Call::Hangup unless call.alive? && call.active?
77
+ raise Call::Hangup unless call.active?
78
78
  @id = SecureRandom.uuid
79
79
  @options, @call = options, call
80
80
  @targets = to.respond_to?(:has_key?) ? to : Array(to)
@@ -168,7 +168,7 @@ module Adhearsion
168
168
  condition.wait
169
169
  end
170
170
 
171
- if new_call.alive? && new_call.active? && status.result != :answer
171
+ if new_call.active? && status.result != :answer
172
172
  logger.info "#dial joining call #{new_call.id} to #{@call.id}"
173
173
  pre_join_tasks new_call
174
174
  @call.answer
@@ -9,7 +9,7 @@ module Adhearsion
9
9
  end
10
10
 
11
11
  def inspect
12
- "#<#{self.class} status=#{status.inspect}, confidence=#{confidence.inspect}, utterance=#{utterance.inspect}, interpretation=#{interpretation.inspect}, nlsml=#{nlsml.inspect}>"
12
+ "#<#{self.class} status=#{status.inspect}, confidence=#{confidence.inspect}, utterance=#{utterance.inspect}, interpretation=#{interpretation.inspect}, nlsml='#{nlsml && nlsml.to_xml.split("\n").join(' ')}'>"
13
13
  end
14
14
 
15
15
  def utterance=(other)
@@ -30,7 +30,7 @@ module Adhearsion
30
30
  #
31
31
  # @return [Adhearsion::Configuration]
32
32
  def initialize(env = :development, &block)
33
- initialize_environments env
33
+ @active_environment = env
34
34
 
35
35
  Loquacious.env_config = true
36
36
  Loquacious.env_prefix = "AHN"
@@ -122,33 +122,14 @@ module Adhearsion
122
122
  self
123
123
  end
124
124
 
125
- def initialize_environments(active_environment)
126
- # Create a method per each valid environment that, when invoked, may execute
127
- # the block received if the environment is active
128
- valid_environments.each do |env|
129
- define_singleton_method env.to_sym do |*args, &block|
130
- logger.trace "Ignoring configuration for inactive environment #{env}"
131
- end
132
- end
133
-
134
- define_singleton_method active_environment do |*args, &block|
135
- self.instance_eval(&block) unless block.nil?
136
- self
137
- end
138
-
139
- if valid_environment?(active_environment)
140
- logger.warn "You tried to initialize with an invalid environment name #{active_environment}; environment-specific config may not load successfully. Valid values are #{valid_environments}."
125
+ def env(environment)
126
+ if environment == @active_environment
127
+ yield self
128
+ else
129
+ logger.trace "Ignoring configuration for inactive environment #{environment}"
141
130
  end
142
131
  end
143
132
 
144
- def valid_environment?(env)
145
- env && self.valid_environments.include?(env.to_sym)
146
- end
147
-
148
- def valid_environments
149
- @valid_environments ||= [:production, :development, :staging, :test]
150
- end
151
-
152
133
  ##
153
134
  # Direct access to a specific configuration object
154
135
  #
@@ -60,17 +60,27 @@ module Adhearsion
60
60
  end
61
61
 
62
62
  def queue
63
- @queue || refresh!
63
+ unless @queue && @queue.alive?
64
+ init
65
+ end
66
+
67
+ @queue
64
68
  end
65
69
 
66
70
  def init
67
- @queue = Worker.pool(size: Adhearsion.config.core.event_threads)
71
+ size = Adhearsion.config.core.event_threads
72
+ logger.debug "Initializing event worker pool of size #{size}"
73
+ @queue = Worker.pool(size: size)
68
74
  end
69
75
 
70
76
  def refresh!
77
+ clear
78
+ init
79
+ end
80
+
81
+ def clear
71
82
  @queue = nil
72
83
  Handler.instance.clear_handlers
73
- init
74
84
  end
75
85
  end
76
86
 
@@ -17,8 +17,8 @@ Adhearsion.config do |config|
17
17
  # config.<plugin-name>.<key> = <value>
18
18
  # end
19
19
  <% end %>
20
- config.development do |dev|
21
- dev.core.logging.level = :debug
20
+ config.env :development do
21
+ config.core.logging.level = :debug
22
22
  end
23
23
 
24
24
  ##
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ class DemoApp < Adhearsion::Application
4
+ app_name :demo
5
+
6
+ # Actions to perform when initialising the application
7
+ #
8
+ init do
9
+ logger.info "This is the Adhearsion Demo application as generated by `ahn create`. It should work well on FreeSWITCH, and will soon also work on Asterisk."
10
+ end
11
+
12
+ # Basic configuration for the application
13
+ #
14
+ config do
15
+ greeting "Hello. Welcome to the Simon Game. Lets play.", desc: "What to use to greet users before playing the Simon Game"
16
+ end
17
+ end
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'adhearsion/application'
3
4
  require 'adhearsion/linux_proc_name'
4
5
  require 'adhearsion/rayo/initializer'
5
6
  require 'adhearsion/http_server'
@@ -28,6 +29,7 @@ module Adhearsion
28
29
  catch :boot_aborted do
29
30
  configure_plugins
30
31
  load_lib_folder
32
+ load_app_file
31
33
  load_config_file
32
34
  load_events_file
33
35
  load_routes_file
@@ -138,6 +140,11 @@ module Adhearsion
138
140
  true
139
141
  end
140
142
 
143
+ def load_app_file
144
+ path = "#{Adhearsion.config.root}/config/app.rb"
145
+ load path if File.exists?(path)
146
+ end
147
+
141
148
  def load_config_file
142
149
  load "#{Adhearsion.config.root}/config/adhearsion.rb"
143
150
  end
@@ -140,10 +140,12 @@ module Adhearsion
140
140
  self.plugin_name = name
141
141
  end
142
142
  end
143
+ alias :app_name :plugin_name
143
144
 
144
145
  def plugin_name=(name)
145
146
  @plugin_name = name
146
147
  end
148
+ alias :app_name= :plugin_name=
147
149
 
148
150
  # Class method that will be used by subclasses to configure the plugin
149
151
  # @param name Symbol plugin config name
@@ -148,6 +148,7 @@ module Adhearsion
148
148
  call.async.deliver_message event
149
149
  else
150
150
  logger.warn "Event received for inactive call #{event.target_call_id}: #{event.inspect}"
151
+ Events.trigger :inactive_call, event
151
152
  end
152
153
  end
153
154
 
@@ -40,7 +40,7 @@ module Adhearsion
40
40
 
41
41
  call.execute_controller controller, lambda { |call_actor|
42
42
  begin
43
- if call_actor.alive? && call_actor.active?
43
+ if call_actor.active?
44
44
  if call_actor.auto_hangup
45
45
  logger.info "Call #{call_id} routing completed. Hanging up now."
46
46
  call_actor.hangup
@@ -70,6 +70,10 @@ module Adhearsion
70
70
  @components[component.id] ||= component
71
71
  end
72
72
 
73
+ def deregister_component(id)
74
+ @components.delete id
75
+ end
76
+
73
77
  def component_with_id(component_id)
74
78
  @components[component_id]
75
79
  end
@@ -145,7 +149,7 @@ module Adhearsion
145
149
  if call = call_with_id(command.uri)
146
150
  command.response = Adhearsion::ProtocolError.new.setup(:conflict, 'Call ID already in use')
147
151
  else
148
- call = Call.new command.to, current_actor, ami_client, connection, nil, command.uri
152
+ call = Call.new command.to, self, ami_client, connection, nil, command.uri
149
153
  register_call call
150
154
  call.dial command
151
155
  end
@@ -225,7 +229,7 @@ module Adhearsion
225
229
 
226
230
  return if env[:agi_extension] == 'h' || env[:agi_type] == 'Kill'
227
231
 
228
- call = Call.new event['Channel'], current_actor, ami_client, connection, env
232
+ call = Call.new event['Channel'], self, ami_client, connection, env
229
233
  register_call call
230
234
  call.send_offer
231
235
  end
@@ -139,7 +139,8 @@ module Adhearsion
139
139
  when 'BridgeEnter'
140
140
  if other_call_channel = translator.bridges.delete(ami_event['BridgeUniqueid'])
141
141
  if other_call = translator.call_for_channel(other_call_channel)
142
- join_command = other_call.pending_joins.delete channel
142
+ join_command = @pending_joins.delete other_call_channel
143
+ join_command ||= other_call.pending_joins.delete channel
143
144
  join_command.response = true if join_command
144
145
 
145
146
  event = Adhearsion::Event::Joined.new call_uri: other_call.id, timestamp: ami_event.best_time
@@ -28,6 +28,7 @@ module Adhearsion
28
28
  event = Adhearsion::Event::Complete.new reason: reason, recording: recording
29
29
  send_event event
30
30
  call.deregister_component id if call
31
+ translator.deregister_component id
31
32
  end
32
33
 
33
34
  def send_event(event)
@@ -18,7 +18,7 @@ module Adhearsion
18
18
  end
19
19
 
20
20
  def stop_by_redirect(complete_reason)
21
- call.register_handler :ami, [{name: 'AsyncAGI', [:[], 'SubEvent'] => 'Start'}, {name: 'AsyncAGIExec'}] do |event|
21
+ call.register_handler :ami, [{name: 'AsyncAGI', [:[], 'SubEvent'] => 'Start'}, {name: 'AsyncAGIStart'}] do |event|
22
22
  send_complete_event complete_reason
23
23
  end
24
24
  call.redirect_back
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Adhearsion
4
- VERSION = '3.0.0.beta1'
4
+ VERSION = '3.0.0.beta2'
5
5
  end
@@ -142,15 +142,15 @@ module Adhearsion
142
142
  describe "#invoke" do
143
143
  class InvokeController < CallController
144
144
  def run
145
- before
145
+ do_before
146
146
  metadata[:invoke_result] = invoke second_controller, :foo => 'bar'
147
- after
147
+ do_after
148
148
  end
149
149
 
150
- def before
150
+ def do_before
151
151
  end
152
152
 
153
- def after
153
+ def do_after
154
154
  end
155
155
 
156
156
  def second_controller
@@ -168,9 +168,9 @@ module Adhearsion
168
168
  end
169
169
 
170
170
  it "should invoke another controller before returning to the current controller" do
171
- expect(subject).to receive(:before).once.ordered
171
+ expect(subject).to receive(:do_before).once.ordered
172
172
  expect(call).to receive(:answer).once.ordered
173
- expect(subject).to receive(:after).once.ordered
173
+ expect(subject).to receive(:do_after).once.ordered
174
174
 
175
175
  subject.exec
176
176
  end
@@ -189,9 +189,9 @@ module Adhearsion
189
189
  it "should allow the outer controller to cease execution and handle remote hangups" do
190
190
  subject[:second_controller] = SecondControllerWithRemoteHangup
191
191
 
192
- expect(subject).to receive(:before).once.ordered
192
+ expect(subject).to receive(:do_before).once.ordered
193
193
  expect(call).to receive(:answer).once.ordered
194
- expect(subject).to receive(:after).never.ordered
194
+ expect(subject).to receive(:do_after).never.ordered
195
195
 
196
196
  subject.exec
197
197
  end
@@ -200,21 +200,22 @@ module Adhearsion
200
200
  describe "#pass" do
201
201
  let(:pass_controller) do
202
202
  Class.new CallController do
203
- after_call :foobar
203
+ after :foobar
204
+ after :doodaz
204
205
 
205
206
  def run
206
- before
207
+ do_before
207
208
  pass SecondController, :foo => 'bar'
208
- after
209
+ do_after
209
210
  end
210
211
 
211
- def before
212
+ def do_before
212
213
  end
213
214
 
214
- def after
215
+ def do_after
215
216
  end
216
217
 
217
- def foobar
218
+ def doodaz
218
219
  end
219
220
  end
220
221
  end
@@ -230,16 +231,17 @@ module Adhearsion
230
231
  end
231
232
 
232
233
  it "should cease execution of the current controller, and instruct the call to execute another" do
233
- expect(subject).to receive(:before).once.ordered
234
+ expect(subject).to receive(:do_before).once.ordered
234
235
  expect(call).to receive(:answer).once.ordered
235
- expect(subject).to receive(:after).never.ordered
236
+ expect(subject).to receive(:do_after).never.ordered
236
237
 
237
238
  subject.exec
238
239
  end
239
240
 
240
- it "should execute after_call callbacks before passing control" do
241
- expect(subject).to receive(:before).once.ordered
241
+ it "should execute after callbacks before passing control" do
242
+ expect(subject).to receive(:do_before).once.ordered
242
243
  expect(subject).to receive(:foobar).once.ordered
244
+ expect(subject).to receive(:doodaz).once.ordered
243
245
  expect(call).to receive(:answer).once.ordered
244
246
 
245
247
  subject.exec
@@ -622,11 +624,13 @@ module Adhearsion
622
624
  end
623
625
 
624
626
  class ExampleCallController < Adhearsion::CallController
625
- before_call { setup_models }
627
+ before { setup_models }
628
+ before :setup_models
626
629
  before_call :setup_models
627
630
 
628
631
  after_call { clean_up_models }
629
- after_call :clean_up_models
632
+ after { clean_up_models }
633
+ after :clean_up_models
630
634
 
631
635
  on_error { apologize_for_failure }
632
636
  on_error :apologize_for_failure
@@ -661,22 +665,22 @@ describe ExampleCallController do
661
665
  allow(call.wrapped_object).to receive_messages :write_and_await_response => nil
662
666
  end
663
667
 
664
- it "should execute the before_call callbacks before processing the call" do
665
- expect(subject).to receive(:setup_models).twice.ordered
668
+ it "should execute the before callbacks before processing the call" do
669
+ expect(subject).to receive(:setup_models).exactly(3).times.ordered
666
670
  expect(subject).to receive(:join_to_conference).once.ordered
667
671
  subject.exec
668
672
  end
669
673
 
670
- it "should execute the after_call callbacks after the call is hung up" do
674
+ it "should execute the after callbacks after the call is hung up" do
671
675
  expect(subject).to receive(:join_to_conference).once.ordered
672
- expect(subject).to receive(:clean_up_models).twice.ordered
676
+ expect(subject).to receive(:clean_up_models).exactly(3).times.ordered
673
677
  expect(subject).to receive(:foobar).never
674
678
  subject.exec
675
679
  end
676
680
 
677
681
  it "should capture errors in callbacks" do
678
- expect(subject).to receive(:setup_models).twice.and_raise StandardError
679
- expect(subject).to receive(:clean_up_models).twice.and_raise StandardError
682
+ expect(subject).to receive(:setup_models).exactly(3).times.and_raise StandardError
683
+ expect(subject).to receive(:clean_up_models).exactly(3).times.and_raise StandardError
680
684
  latch = CountDownLatch.new 4
681
685
  Adhearsion::Events.exception do |e, l|
682
686
  expect(e).to be_a StandardError
@@ -695,11 +699,11 @@ describe ExampleCallController do
695
699
  end
696
700
 
697
701
  describe "when the controller finishes without a hangup" do
698
- it "should execute the after_call callbacks" do
702
+ it "should execute the after callbacks" do
699
703
  subject[:skip_hangup] = true
700
704
  expect(subject).to receive(:join_to_conference).once.ordered
701
705
  expect(subject).to receive(:foobar).once.ordered
702
- expect(subject).to receive(:clean_up_models).twice.ordered
706
+ expect(subject).to receive(:clean_up_models).exactly(3).times.ordered
703
707
  subject.exec
704
708
  end
705
709
  end
@@ -633,6 +633,7 @@ module Adhearsion
633
633
  subject << end_event
634
634
  sleep 2.1
635
635
  expect(subject.alive?).to be false
636
+ expect(subject.active?).to be false
636
637
  expect { subject.id }.to raise_error Call::ExpiredError, /expired and is no longer accessible/
637
638
  end
638
639
  end
@@ -653,8 +654,10 @@ module Adhearsion
653
654
  subject << end_event
654
655
  sleep 1.1
655
656
  expect(subject.alive?).to be true
657
+ expect(subject.active?).to be false
656
658
  sleep 1
657
659
  expect(subject.alive?).to be false
660
+ expect(subject.active?).to be false
658
661
  expect { subject.id }.to raise_error Call::ExpiredError, /expired and is no longer accessible/
659
662
  end
660
663
  end
@@ -98,17 +98,17 @@ describe Adhearsion::Configuration do
98
98
  end
99
99
 
100
100
  before do
101
- subject.production do |env|
102
- env.core.my_level = 0
101
+ subject.env :production do
102
+ subject.core.my_level = 0
103
103
  end
104
- subject.development do |env|
105
- env.core.my_level = 1
104
+ subject.env :development do
105
+ subject.core.my_level = 1
106
106
  end
107
- subject.staging do |env|
108
- env.core.my_level = 2
107
+ subject.env :staging do
108
+ subject.core.my_level = 2
109
109
  end
110
- subject.test do |env|
111
- env.core.my_level = 3
110
+ subject.env :test do
111
+ subject.core.my_level = 3
112
112
  end
113
113
  end
114
114
 
@@ -133,31 +133,6 @@ describe Adhearsion::Configuration do
133
133
  end
134
134
  end
135
135
 
136
- describe "while defining the environment" do
137
-
138
- before do
139
- Adhearsion.config = nil
140
- end
141
-
142
- after do
143
- Adhearsion.environment = nil
144
- Adhearsion.config = nil
145
- end
146
-
147
- [:development, :production, :staging, :test].each do |env|
148
- it "should respond to #{env}" do
149
- expect(Adhearsion.config).to respond_to(env)
150
- end
151
- end
152
-
153
- it "should allow to add a new environment" do
154
- expect(Adhearsion.config.valid_environment?(:another_environment)).to eq(false)
155
- Adhearsion.environments << :another_environment
156
- expect(Adhearsion.config.valid_environment?(:another_environment)).to eq(true)
157
- end
158
-
159
- end
160
-
161
136
  describe "while retrieving configuration descriptions" do
162
137
  before do
163
138
  Adhearsion.config = nil
@@ -222,17 +197,17 @@ describe Adhearsion::Configuration do
222
197
  end
223
198
 
224
199
  before do
225
- config.production do |env|
226
- env.my_plugin.name = "production"
200
+ config.env :production do
201
+ config.my_plugin.name = "production"
227
202
  end
228
- config.development do |env|
229
- env.my_plugin.name = "development"
203
+ config.env :development do
204
+ config.my_plugin.name = "development"
230
205
  end
231
- config.staging do |env|
232
- env.my_plugin.name = "staging"
206
+ config.env :staging do
207
+ config.my_plugin.name = "staging"
233
208
  end
234
- config.test do |env|
235
- env.my_plugin.name = "test"
209
+ config.env :test do
210
+ config.my_plugin.name = "test"
236
211
  end
237
212
  end
238
213
 
@@ -162,6 +162,7 @@ describe Adhearsion::Rayo::Initializer do
162
162
  end
163
163
 
164
164
  it 'should not attempt to reconnect if Adhearsion is shutting down' do
165
+ skip 'Strange interaction with specs restarting Celluloid; TODO re-consider along with migration to actors for Process/connection management'
165
166
  Adhearsion::Process.booted
166
167
  Adhearsion::Process.shutdown
167
168
  allow(mock_client).to receive(:run).and_raise Adhearsion::Rayo::DisconnectedError
@@ -295,6 +296,11 @@ describe Adhearsion::Rayo::Initializer do
295
296
  expect(Adhearsion::Logging.get_logger(described_class)).to receive(:warn).once.with("Event received for inactive call #{call_id}: #{mock_event.inspect}")
296
297
  described_class.dispatch_call_event mock_event
297
298
  end
299
+
300
+ it "should trigger an inactive call event" do
301
+ expect(Adhearsion::Events).to receive(:trigger).once.with(:inactive_call, mock_event)
302
+ described_class.dispatch_call_event mock_event
303
+ end
298
304
  end
299
305
 
300
306
  describe "when the registry contains a dead call" do
@@ -832,11 +832,11 @@ module Adhearsion
832
832
  Adhearsion::Rayo::Command::Join.new call_uri: other_call_id
833
833
  end
834
834
 
835
- let :ami_event do
835
+ let :second_ami_event do
836
836
  RubyAMI::Event.new 'BridgeEnter',
837
837
  'Privilege' => "call,all",
838
838
  'BridgeUniqueid' => bridge_uniqueid,
839
- 'Channel' => call_channel
839
+ 'Channel' => other_channel
840
840
  end
841
841
 
842
842
  let :expected_joined do
@@ -850,27 +850,49 @@ module Adhearsion
850
850
  end
851
851
 
852
852
  before do
853
- translator.bridges[bridge_uniqueid] = other_channel
853
+ translator.register_call subject
854
854
  translator.register_call other_call
855
-
856
- other_call.pending_joins[channel] = command
857
855
  command.request!
858
856
  expect(subject).to receive(:execute_agi_command).and_return code: 200
859
857
  subject.execute_command command
858
+ translator.handle_ami_event ami_event
860
859
  end
861
860
 
862
861
  it 'sends the correct Joined events' do
863
862
  expect(translator).to receive(:handle_pb_event).with expected_joined
864
863
  expect(translator).to receive(:handle_pb_event).with expected_joined_other
865
- subject.process_ami_event ami_event
864
+ translator.handle_ami_event second_ami_event
866
865
  expect(command.response(0.5)).to eq(true)
867
866
  end
867
+
868
+ context 'out of order' do
869
+ let :ami_event do
870
+ RubyAMI::Event.new 'BridgeEnter',
871
+ 'Privilege' => "call,all",
872
+ 'BridgeUniqueid' => bridge_uniqueid,
873
+ 'Channel' => other_channel
874
+ end
875
+
876
+ let :second_ami_event do
877
+ RubyAMI::Event.new 'BridgeEnter',
878
+ 'Privilege' => "call,all",
879
+ 'BridgeUniqueid' => bridge_uniqueid,
880
+ 'Channel' => call_channel
881
+ end
882
+
883
+ it 'sends the correct Joined events' do
884
+ expect(translator).to receive(:handle_pb_event).with expected_joined
885
+ expect(translator).to receive(:handle_pb_event).with expected_joined_other
886
+ translator.handle_ami_event second_ami_event
887
+ expect(command.response(0.5)).to eq(true)
888
+ end
889
+ end
868
890
  end
869
891
  end
870
892
 
871
893
  context 'with a BridgeLeave event' do
872
894
  let(:bridge_uniqueid) { "1234-5678" }
873
- let(:call_channel) { "SIP/foo-1234" }
895
+ let(:call_channel) { "SIP/foo" }
874
896
  let :ami_event do
875
897
  RubyAMI::Event.new 'BridgeLeave',
876
898
  'Privilege' => "call,all",
@@ -892,11 +914,11 @@ module Adhearsion
892
914
  end
893
915
  let(:other_call_id) { other_call.id }
894
916
 
895
- let :ami_event do
917
+ let :second_ami_event do
896
918
  RubyAMI::Event.new 'BridgeLeave',
897
919
  'Privilege' => "call,all",
898
920
  'BridgeUniqueid' => bridge_uniqueid,
899
- 'Channel' => call_channel
921
+ 'Channel' => other_channel
900
922
  end
901
923
 
902
924
  let :expected_unjoined do
@@ -910,14 +932,37 @@ module Adhearsion
910
932
  end
911
933
 
912
934
  before do
913
- translator.bridges[bridge_uniqueid + '_leave'] = other_channel
935
+ translator.register_call subject
914
936
  translator.register_call other_call
937
+ translator.handle_ami_event ami_event
915
938
  end
916
939
 
917
940
  it 'sends the correct Unjoined events' do
918
941
  expect(translator).to receive(:handle_pb_event).with expected_unjoined
919
942
  expect(translator).to receive(:handle_pb_event).with expected_unjoined_other
920
- subject.process_ami_event ami_event
943
+ translator.handle_ami_event second_ami_event
944
+ end
945
+
946
+ context 'out of order' do
947
+ let :ami_event do
948
+ RubyAMI::Event.new 'BridgeLeave',
949
+ 'Privilege' => "call,all",
950
+ 'BridgeUniqueid' => bridge_uniqueid,
951
+ 'Channel' => other_channel
952
+ end
953
+
954
+ let :second_ami_event do
955
+ RubyAMI::Event.new 'BridgeLeave',
956
+ 'Privilege' => "call,all",
957
+ 'BridgeUniqueid' => bridge_uniqueid,
958
+ 'Channel' => call_channel
959
+ end
960
+
961
+ it 'sends the correct Unjoined events' do
962
+ expect(translator).to receive(:handle_pb_event).with expected_unjoined
963
+ expect(translator).to receive(:handle_pb_event).with expected_unjoined_other
964
+ translator.handle_ami_event second_ami_event
965
+ end
921
966
  end
922
967
  end
923
968
  end
@@ -42,7 +42,7 @@ module Adhearsion
42
42
 
43
43
  it "sets the command response to true" do
44
44
  expect(mock_call).to receive(:redirect_back)
45
- expect(mock_call).to receive(:register_handler).once.with(:ami, [{:name => 'AsyncAGI', [:[], 'SubEvent']=>'Start'}, {:name => 'AsyncAGIExec'}])
45
+ expect(mock_call).to receive(:register_handler).once.with(:ami, [{:name => 'AsyncAGI', [:[], 'SubEvent']=>'Start'}, {:name => 'AsyncAGIStart'}])
46
46
 
47
47
  subject.execute_command command
48
48
  expect(command.response(0.1)).to eq(true)
@@ -58,6 +58,15 @@ module Adhearsion
58
58
  expect(subject).to receive(:send_complete_event).once.with Adhearsion::Event::Complete::Hangup.new
59
59
  subject.call_ended
60
60
  end
61
+
62
+ it "should deregister component from translator" do
63
+ translator.register_component(subject)
64
+ expect(translator.component_with_id(subject.id)).not_to be nil
65
+ expect(translator).to receive(:handle_pb_event).once
66
+ subject.call_ended
67
+ expect(translator.component_with_id(subject.id)).to be nil
68
+ end
69
+
61
70
  end
62
71
 
63
72
  describe '#execute_command' do
@@ -36,13 +36,6 @@ describe Adhearsion do
36
36
  end
37
37
  end
38
38
 
39
- describe "#environments" do
40
- it "should be the collection of valid environments" do
41
- Adhearsion.config.valid_environments << :foo
42
- expect(Adhearsion.environments).to include :foo
43
- end
44
- end
45
-
46
39
  describe "#router" do
47
40
  describe '#router' do
48
41
  subject { super().router }
@@ -48,11 +48,11 @@ RSpec.configure do |config|
48
48
 
49
49
  config.after :each do
50
50
  Timecop.return
51
+ Adhearsion::Events.clear
51
52
  if defined?(:Celluloid)
52
53
  Celluloid.shutdown
53
54
  Adhearsion.active_calls = nil
54
55
  Celluloid.boot
55
- Adhearsion::Events.refresh!
56
56
  end
57
57
  end
58
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adhearsion
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta1
4
+ version: 3.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jay Phillips
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-06-24 00:00:00.000000000 Z
14
+ date: 2015-12-18 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -81,14 +81,14 @@ dependencies:
81
81
  requirements:
82
82
  - - "~>"
83
83
  - !ruby/object:Gem::Version
84
- version: '0.16'
84
+ version: 0.16.0
85
85
  type: :runtime
86
86
  prerelease: false
87
87
  version_requirements: !ruby/object:Gem::Requirement
88
88
  requirements:
89
89
  - - "~>"
90
90
  - !ruby/object:Gem::Version
91
- version: '0.16'
91
+ version: 0.16.0
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: countdownlatch
94
94
  requirement: !ruby/object:Gem::Requirement
@@ -165,6 +165,20 @@ dependencies:
165
165
  - - ">="
166
166
  - !ruby/object:Gem::Version
167
167
  version: 1.6.3
168
+ - !ruby/object:Gem::Dependency
169
+ name: http
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: 0.9.8
175
+ type: :runtime
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: 0.9.8
168
182
  - !ruby/object:Gem::Dependency
169
183
  name: i18n
170
184
  requirement: !ruby/object:Gem::Requirement
@@ -185,14 +199,14 @@ dependencies:
185
199
  requirements:
186
200
  - - "~>"
187
201
  - !ruby/object:Gem::Version
188
- version: '1.8'
202
+ version: '2.0'
189
203
  type: :runtime
190
204
  prerelease: false
191
205
  version_requirements: !ruby/object:Gem::Requirement
192
206
  requirements:
193
207
  - - "~>"
194
208
  - !ruby/object:Gem::Version
195
- version: '1.8'
209
+ version: '2.0'
196
210
  - !ruby/object:Gem::Dependency
197
211
  name: nokogiri
198
212
  requirement: !ruby/object:Gem::Requirement
@@ -359,14 +373,14 @@ dependencies:
359
373
  requirements:
360
374
  - - "~>"
361
375
  - !ruby/object:Gem::Version
362
- version: '0.5'
376
+ version: 0.6.0
363
377
  type: :development
364
378
  prerelease: false
365
379
  version_requirements: !ruby/object:Gem::Requirement
366
380
  requirements:
367
381
  - - "~>"
368
382
  - !ruby/object:Gem::Version
369
- version: '0.5'
383
+ version: 0.6.0
370
384
  - !ruby/object:Gem::Dependency
371
385
  name: ci_reporter_rspec
372
386
  requirement: !ruby/object:Gem::Requirement
@@ -544,6 +558,7 @@ extra_rdoc_files: []
544
558
  files:
545
559
  - ".gitignore"
546
560
  - ".hound.yml"
561
+ - ".lgtm"
547
562
  - ".rspec"
548
563
  - ".travis.yml"
549
564
  - ".yardopts"
@@ -552,6 +567,7 @@ files:
552
567
  - Gemfile
553
568
  - Guardfile
554
569
  - LICENSE
570
+ - MAINTAINERS
555
571
  - README.markdown
556
572
  - Rakefile
557
573
  - adhearsion.gemspec
@@ -568,6 +584,7 @@ files:
568
584
  - features/step_definitions/cli_steps.rb
569
585
  - features/support/env.rb
570
586
  - lib/adhearsion.rb
587
+ - lib/adhearsion/application.rb
571
588
  - lib/adhearsion/call.rb
572
589
  - lib/adhearsion/call_controller.rb
573
590
  - lib/adhearsion/call_controller/dial.rb
@@ -623,6 +640,7 @@ files:
623
640
  - lib/adhearsion/generators/app/templates/Rakefile
624
641
  - lib/adhearsion/generators/app/templates/adhearsion.erb
625
642
  - lib/adhearsion/generators/app/templates/config.ru
643
+ - lib/adhearsion/generators/app/templates/config/app.rb
626
644
  - lib/adhearsion/generators/app/templates/config/environment.rb
627
645
  - lib/adhearsion/generators/app/templates/en.yml
628
646
  - lib/adhearsion/generators/app/templates/events.erb