adhearsion 3.0.0.beta1 → 3.0.0.beta2

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.
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