adhearsion 1.2.6 → 2.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (236) hide show
  1. data/.gitignore +17 -10
  2. data/CHANGELOG.md +273 -0
  3. data/Gemfile +1 -1
  4. data/Guardfile +17 -0
  5. data/README.markdown +61 -9
  6. data/Rakefile +16 -48
  7. data/adhearsion.gemspec +21 -7
  8. data/bin/ahn +3 -1
  9. data/cucumber.yml +4 -0
  10. data/features/app_generator.feature +42 -0
  11. data/features/cli.feature +108 -0
  12. data/features/step_definitions/app_generator_steps.rb +6 -0
  13. data/features/step_definitions/cli_steps.rb +74 -0
  14. data/features/support/aruba_helper.rb +22 -0
  15. data/features/support/env.rb +37 -0
  16. data/features/support/utils.rb +8 -0
  17. data/lib/adhearsion.rb +85 -41
  18. data/lib/adhearsion/call.rb +176 -0
  19. data/lib/adhearsion/call_controller.rb +134 -0
  20. data/lib/adhearsion/call_controller/dial.rb +70 -0
  21. data/lib/adhearsion/call_controller/input.rb +173 -0
  22. data/lib/adhearsion/call_controller/menu.rb +124 -0
  23. data/lib/adhearsion/call_controller/output.rb +267 -0
  24. data/lib/adhearsion/call_controller/record.rb +42 -0
  25. data/lib/adhearsion/call_controller/utility.rb +60 -0
  26. data/lib/adhearsion/calls.rb +81 -0
  27. data/lib/adhearsion/cli.rb +1 -3
  28. data/lib/adhearsion/cli_commands.rb +142 -0
  29. data/lib/adhearsion/configuration.rb +149 -0
  30. data/lib/adhearsion/console.rb +19 -8
  31. data/lib/adhearsion/dialplan_controller.rb +9 -0
  32. data/lib/adhearsion/events.rb +84 -0
  33. data/lib/adhearsion/foundation/all.rb +0 -7
  34. data/lib/adhearsion/foundation/custom_daemonizer.rb +4 -6
  35. data/lib/adhearsion/foundation/exception_handler.rb +9 -0
  36. data/lib/adhearsion/foundation/object.rb +26 -8
  37. data/lib/adhearsion/foundation/synchronized_hash.rb +3 -6
  38. data/lib/adhearsion/foundation/thread_safety.rb +17 -1
  39. data/lib/adhearsion/generators/app/app_generator.rb +4 -13
  40. data/lib/adhearsion/generators/app/templates/Gemfile +10 -5
  41. data/lib/adhearsion/generators/app/templates/Procfile +1 -0
  42. data/lib/adhearsion/generators/app/templates/README.md +28 -0
  43. data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +41 -0
  44. data/lib/adhearsion/generators/app/templates/{components/simon_game → lib}/simon_game.rb +6 -18
  45. data/lib/adhearsion/generators/app/templates/script/ahn +2 -2
  46. data/lib/adhearsion/initializer.rb +151 -293
  47. data/lib/adhearsion/initializer/logging.rb +33 -0
  48. data/lib/adhearsion/logging.rb +65 -69
  49. data/lib/adhearsion/menu_dsl.rb +15 -0
  50. data/lib/adhearsion/menu_dsl/calculated_match.rb +39 -0
  51. data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +41 -0
  52. data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +18 -0
  53. data/lib/adhearsion/menu_dsl/match_calculator.rb +36 -0
  54. data/lib/adhearsion/{voip/menu_state_machine/menu_class.rb → menu_dsl/menu.rb} +38 -40
  55. data/lib/adhearsion/menu_dsl/menu_builder.rb +69 -0
  56. data/lib/adhearsion/menu_dsl/range_match_calculator.rb +55 -0
  57. data/lib/adhearsion/menu_dsl/string_match_calculator.rb +21 -0
  58. data/lib/adhearsion/outbound_call.rb +64 -0
  59. data/lib/adhearsion/plugin.rb +319 -0
  60. data/lib/adhearsion/plugin/collection.rb +19 -0
  61. data/lib/adhearsion/plugin/initializer.rb +37 -0
  62. data/lib/adhearsion/plugin/methods_container.rb +6 -0
  63. data/lib/adhearsion/process.rb +94 -0
  64. data/lib/adhearsion/punchblock_plugin.rb +29 -0
  65. data/lib/adhearsion/punchblock_plugin/initializer.rb +137 -0
  66. data/lib/adhearsion/router.rb +30 -0
  67. data/lib/adhearsion/router/route.rb +42 -0
  68. data/lib/adhearsion/script_ahn_loader.rb +2 -2
  69. data/lib/adhearsion/tasks.rb +14 -9
  70. data/lib/adhearsion/tasks/configuration.rb +26 -0
  71. data/lib/adhearsion/tasks/plugins.rb +17 -0
  72. data/lib/adhearsion/version.rb +8 -14
  73. data/spec/adhearsion/call_controller/dial_spec.rb +138 -0
  74. data/spec/adhearsion/call_controller/input_spec.rb +278 -0
  75. data/spec/adhearsion/call_controller/menu_spec.rb +120 -0
  76. data/spec/adhearsion/call_controller/output_spec.rb +466 -0
  77. data/spec/adhearsion/call_controller/record_spec.rb +125 -0
  78. data/spec/adhearsion/call_controller_spec.rb +395 -0
  79. data/spec/adhearsion/call_spec.rb +438 -0
  80. data/spec/adhearsion/calls_spec.rb +47 -0
  81. data/spec/adhearsion/configuration_spec.rb +308 -0
  82. data/spec/adhearsion/dialplan_controller_spec.rb +26 -0
  83. data/spec/adhearsion/events_spec.rb +112 -0
  84. data/spec/adhearsion/initializer/logging_spec.rb +58 -0
  85. data/spec/adhearsion/initializer_spec.rb +209 -122
  86. data/spec/adhearsion/logging_spec.rb +58 -47
  87. data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +56 -0
  88. data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +57 -0
  89. data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +33 -0
  90. data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +13 -0
  91. data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +118 -0
  92. data/spec/adhearsion/menu_dsl/menu_spec.rb +210 -0
  93. data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +28 -0
  94. data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +36 -0
  95. data/spec/adhearsion/menu_dsl_spec.rb +12 -0
  96. data/spec/adhearsion/outbound_call_spec.rb +174 -0
  97. data/spec/adhearsion/plugin_spec.rb +489 -0
  98. data/spec/adhearsion/process_spec.rb +34 -0
  99. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +294 -0
  100. data/spec/adhearsion/router/route_spec.rb +99 -0
  101. data/spec/adhearsion/router_spec.rb +106 -0
  102. data/spec/adhearsion_spec.rb +46 -0
  103. data/spec/spec_helper.rb +14 -14
  104. data/spec/support/call_controller_test_helpers.rb +48 -0
  105. data/spec/support/initializer_stubs.rb +8 -13
  106. data/spec/support/punchblock_mocks.rb +6 -0
  107. metadata +255 -253
  108. data/CHANGELOG +0 -174
  109. data/bin/ahnctl +0 -68
  110. data/bin/jahn +0 -43
  111. data/examples/asterisk_manager_interface/standalone.rb +0 -51
  112. data/lib/adhearsion/commands.rb +0 -302
  113. data/lib/adhearsion/component_manager.rb +0 -278
  114. data/lib/adhearsion/component_manager/component_tester.rb +0 -54
  115. data/lib/adhearsion/component_manager/spec_framework.rb +0 -18
  116. data/lib/adhearsion/events_support.rb +0 -65
  117. data/lib/adhearsion/foundation/blank_slate.rb +0 -3
  118. data/lib/adhearsion/foundation/event_socket.rb +0 -205
  119. data/lib/adhearsion/foundation/future_resource.rb +0 -36
  120. data/lib/adhearsion/foundation/metaprogramming.rb +0 -17
  121. data/lib/adhearsion/foundation/numeric.rb +0 -13
  122. data/lib/adhearsion/foundation/pseudo_guid.rb +0 -10
  123. data/lib/adhearsion/foundation/relationship_properties.rb +0 -42
  124. data/lib/adhearsion/foundation/string.rb +0 -26
  125. data/lib/adhearsion/generators/app/templates/.ahnrc +0 -34
  126. data/lib/adhearsion/generators/app/templates/README +0 -8
  127. data/lib/adhearsion/generators/app/templates/components/ami_remote/ami_remote.rb +0 -15
  128. data/lib/adhearsion/generators/app/templates/components/disabled/HOW_TO_ENABLE +0 -7
  129. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/README.markdown +0 -47
  130. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.rb +0 -34
  131. data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.yml +0 -12
  132. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/README.markdown +0 -3
  133. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +0 -11
  134. data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
  135. data/lib/adhearsion/generators/app/templates/config/startup.rb +0 -81
  136. data/lib/adhearsion/generators/app/templates/dialplan.rb +0 -3
  137. data/lib/adhearsion/generators/app/templates/events.rb +0 -33
  138. data/lib/adhearsion/host_definitions.rb +0 -67
  139. data/lib/adhearsion/initializer/asterisk.rb +0 -86
  140. data/lib/adhearsion/initializer/configuration.rb +0 -324
  141. data/lib/adhearsion/initializer/database.rb +0 -60
  142. data/lib/adhearsion/initializer/drb.rb +0 -31
  143. data/lib/adhearsion/initializer/freeswitch.rb +0 -22
  144. data/lib/adhearsion/initializer/ldap.rb +0 -57
  145. data/lib/adhearsion/initializer/rails.rb +0 -41
  146. data/lib/adhearsion/initializer/xmpp.rb +0 -42
  147. data/lib/adhearsion/tasks/components.rb +0 -32
  148. data/lib/adhearsion/tasks/database.rb +0 -5
  149. data/lib/adhearsion/tasks/deprecations.rb +0 -59
  150. data/lib/adhearsion/tasks/generating.rb +0 -20
  151. data/lib/adhearsion/tasks/lint.rb +0 -4
  152. data/lib/adhearsion/voip/asterisk.rb +0 -4
  153. data/lib/adhearsion/voip/asterisk/agi_server.rb +0 -121
  154. data/lib/adhearsion/voip/asterisk/commands.rb +0 -1966
  155. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +0 -140
  156. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +0 -102
  157. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +0 -250
  158. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +0 -240
  159. data/lib/adhearsion/voip/asterisk/config_manager.rb +0 -64
  160. data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -697
  161. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +0 -1681
  162. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +0 -341
  163. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +0 -78
  164. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +0 -87
  165. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +0 -80
  166. data/lib/adhearsion/voip/call.rb +0 -521
  167. data/lib/adhearsion/voip/call_routing.rb +0 -64
  168. data/lib/adhearsion/voip/commands.rb +0 -17
  169. data/lib/adhearsion/voip/constants.rb +0 -39
  170. data/lib/adhearsion/voip/conveniences.rb +0 -18
  171. data/lib/adhearsion/voip/dial_plan.rb +0 -252
  172. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +0 -151
  173. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +0 -37
  174. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +0 -27
  175. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +0 -124
  176. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +0 -69
  177. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +0 -16
  178. data/lib/adhearsion/voip/dsl/numerical_string.rb +0 -128
  179. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +0 -48
  180. data/lib/adhearsion/voip/freeswitch/event_handler.rb +0 -58
  181. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +0 -129
  182. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +0 -38
  183. data/lib/adhearsion/voip/freeswitch/oes_server.rb +0 -195
  184. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +0 -80
  185. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +0 -123
  186. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +0 -57
  187. data/lib/adhearsion/xmpp/connection.rb +0 -61
  188. data/lib/theatre.rb +0 -147
  189. data/lib/theatre/README.markdown +0 -64
  190. data/lib/theatre/callback_definition_loader.rb +0 -86
  191. data/lib/theatre/guid.rb +0 -23
  192. data/lib/theatre/invocation.rb +0 -131
  193. data/lib/theatre/namespace_manager.rb +0 -153
  194. data/lib/theatre/version.rb +0 -2
  195. data/spec/adhearsion/cli_spec.rb +0 -306
  196. data/spec/adhearsion/component_manager_spec.rb +0 -292
  197. data/spec/adhearsion/constants_spec.rb +0 -8
  198. data/spec/adhearsion/drb_spec.rb +0 -65
  199. data/spec/adhearsion/fixtures/dialplan.rb +0 -3
  200. data/spec/adhearsion/foundation/event_socket_spec.rb +0 -168
  201. data/spec/adhearsion/host_definitions_spec.rb +0 -79
  202. data/spec/adhearsion/initializer/configuration_spec.rb +0 -291
  203. data/spec/adhearsion/initializer/loading_spec.rb +0 -154
  204. data/spec/adhearsion/initializer/paths_spec.rb +0 -74
  205. data/spec/adhearsion/relationship_properties_spec.rb +0 -54
  206. data/spec/adhearsion/voip/asterisk/agi_server_spec.rb +0 -473
  207. data/spec/adhearsion/voip/asterisk/ami/ami_spec.rb +0 -550
  208. data/spec/adhearsion/voip/asterisk/ami/lexer/ami_fixtures.yml +0 -30
  209. data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story +0 -291
  210. data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story.rb +0 -241
  211. data/spec/adhearsion/voip/asterisk/ami/lexer/story_helper.rb +0 -124
  212. data/spec/adhearsion/voip/asterisk/commands_spec.rb +0 -3241
  213. data/spec/adhearsion/voip/asterisk/config_file_generators/agents_spec.rb +0 -251
  214. data/spec/adhearsion/voip/asterisk/config_file_generators/queues_spec.rb +0 -323
  215. data/spec/adhearsion/voip/asterisk/config_file_generators/voicemail_spec.rb +0 -306
  216. data/spec/adhearsion/voip/asterisk/config_manager_spec.rb +0 -127
  217. data/spec/adhearsion/voip/asterisk/menu_command/calculated_match_spec.rb +0 -109
  218. data/spec/adhearsion/voip/asterisk/menu_command/matchers_spec.rb +0 -97
  219. data/spec/adhearsion/voip/call_routing_spec.rb +0 -125
  220. data/spec/adhearsion/voip/dialplan_manager_spec.rb +0 -468
  221. data/spec/adhearsion/voip/dsl/dialing_dsl_spec.rb +0 -270
  222. data/spec/adhearsion/voip/dsl/dispatcher_spec.rb +0 -82
  223. data/spec/adhearsion/voip/dsl/dispatcher_spec_helper.rb +0 -45
  224. data/spec/adhearsion/voip/dsl/parser_spec.rb +0 -69
  225. data/spec/adhearsion/voip/freeswitch/basic_connection_manager_spec.rb +0 -39
  226. data/spec/adhearsion/voip/freeswitch/inbound_connection_manager_spec.rb +0 -39
  227. data/spec/adhearsion/voip/freeswitch/oes_server_spec.rb +0 -9
  228. data/spec/adhearsion/voip/numerical_string_spec.rb +0 -61
  229. data/spec/adhearsion/voip/phone_number_spec.rb +0 -45
  230. data/spec/support/the_following_code.rb +0 -3
  231. data/spec/theatre/dsl_examples/simple_before_call.rb +0 -7
  232. data/spec/theatre/dsl_spec.rb +0 -69
  233. data/spec/theatre/invocation_spec.rb +0 -182
  234. data/spec/theatre/namespace_spec.rb +0 -125
  235. data/spec/theatre/spec_helper_spec.rb +0 -28
  236. data/spec/theatre/theatre_class_spec.rb +0 -148
@@ -0,0 +1,19 @@
1
+ require 'tsort'
2
+
3
+ module Adhearsion
4
+ class Plugin
5
+ class Collection < Array
6
+ include TSort
7
+
8
+ alias :tsort_each_node :each
9
+
10
+ def tsort_each_child(child, &block)
11
+ select { |i| i.before == child.name || i.name == child.after }.each &block
12
+ end
13
+
14
+ def +(other)
15
+ Collection.new(to_a + other.to_a)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ module Adhearsion
2
+ class Plugin
3
+ class Initializer
4
+ attr_reader :name, :block
5
+
6
+ def initialize(name, context, options, &block)
7
+ options[:group] ||= :default
8
+ @name, @context, @options, @block = name, context, options, block
9
+ end
10
+
11
+ def before
12
+ @options[:before]
13
+ end
14
+
15
+ def after
16
+ @options[:after]
17
+ end
18
+
19
+ def belongs_to?(group)
20
+ @options[:group] == group || @options[:group] == :all
21
+ end
22
+
23
+ def run(*args)
24
+ @context.instance_exec *args, &block
25
+ end
26
+
27
+ def bind(context)
28
+ return self if @context
29
+ Initializer.new @name, context, @options, &block
30
+ end
31
+
32
+ def to_s
33
+ "#{self.name}: #{@options}"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+ module Adhearsion
2
+ class Plugin
3
+ class MethodsContainer < Hash
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,94 @@
1
+ require 'state_machine'
2
+ require 'singleton'
3
+
4
+ module Adhearsion
5
+ class Process
6
+ include Singleton
7
+
8
+ state_machine :initial => :booting do
9
+ before_transition :log_state_change
10
+ after_transition :on => :shutdown, :do => :request_stop
11
+ after_transition any => :stopped, :do => :final_shutdown
12
+ after_transition :on => :force_stop, :do => :die_now!
13
+
14
+ event :booted do
15
+ transition :booting => :running
16
+ end
17
+
18
+ event :shutdown do
19
+ # On first shutdown request, flag our state but continue otherwise normally.
20
+ transition :running => :stopping
21
+
22
+ # On second shutdown request, start rejecting new calls.
23
+ # This corresponds to the admin pressing CTRL+C twice.
24
+ transition :stopping => :rejecting
25
+
26
+ # On third shutdown request, hang up all active calls.
27
+ # This corresponds to the admin pressing CTRL+C three times.
28
+ transition :rejecting => :stopped
29
+
30
+ # If we are still booting, transition directly to stopped
31
+ transition :booting => :force_stop
32
+ end
33
+
34
+ event :hard_shutdown do
35
+ transition [:running, :stopping] => :rejecting
36
+ end
37
+
38
+ event :stop do
39
+ transition :rejecting => :stopped
40
+ end
41
+
42
+ event :force_stop do
43
+ transition all => :force_stopped
44
+ end
45
+
46
+ event :reset do
47
+ transition all => :booting
48
+ end
49
+ end
50
+
51
+ attr_accessor :important_threads
52
+
53
+ def initialize
54
+ @important_threads = ThreadSafeArray.new
55
+ super
56
+ end
57
+
58
+ def log_state_change(transition)
59
+ event, from, to = transition.event, transition.from_name, transition.to_name
60
+ logger.info "Transitioning from #{from} to #{to} with #{Adhearsion.active_calls.size} active calls."
61
+ end
62
+
63
+ def request_stop
64
+ Events.trigger_immediately :stop_requested
65
+ important_threads << Thread.new { stop_when_zero_calls }
66
+ end
67
+
68
+ def final_shutdown
69
+ Adhearsion.active_calls.each do |call|
70
+ call.hangup
71
+ end
72
+ # This should shut down any remaining threads. Once those threads have
73
+ # stopped, important_threads will be empty and the process will exit
74
+ # normally.
75
+ Events.trigger_immediately :shutdown
76
+ end
77
+
78
+ def stop_when_zero_calls
79
+ until Adhearsion.active_calls.count == 0
80
+ logger.trace "Stop requested but we still have #{Adhearsion.active_calls.count} active calls."
81
+ sleep 0.2
82
+ end
83
+ final_shutdown
84
+ end
85
+
86
+ def die_now!
87
+ ::Process.exit 1
88
+ end
89
+
90
+ def self.method_missing(method_name, *args, &block)
91
+ instance.send method_name, *args, &block
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,29 @@
1
+ module Adhearsion
2
+ class PunchblockPlugin < Plugin
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Initializer
6
+
7
+ config :punchblock do
8
+ platform :xmpp , :desc => <<-__
9
+ Platform punchblock shall use to connect to the Telephony provider. Currently supported values:
10
+ - :xmpp
11
+ - :asterisk
12
+ __
13
+ username "usera@127.0.0.1", :desc => "Authentication credentials"
14
+ password "1" , :desc => "Authentication credentials"
15
+ host nil , :desc => "Host punchblock needs to connect (where rayo or asterisk are located)"
16
+ port nil , :desc => "Port punchblock needs to connect (by default 5038 for Asterisk, 5222 for Rayo)"
17
+ root_domain nil , :desc => "The root domain at which to address the server"
18
+ calls_domain nil , :desc => "The domain at which to address calls"
19
+ mixers_domain nil , :desc => "The domain at which to address mixers"
20
+ connection_timeout 60 , :desc => "The amount of time to wait for a connection"
21
+ reconnect_attempts 1.0/0.0 , :desc => "The number of times to (re)attempt connection to the server"
22
+ reconnect_timer 5 , :desc => "Delay between connection attempts"
23
+ end
24
+
25
+ init :punchblock do
26
+ Initializer.start
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,137 @@
1
+ module Adhearsion
2
+ class PunchblockPlugin
3
+ class Initializer
4
+ cattr_accessor :config, :client, :dispatcher, :attempts
5
+
6
+ self.attempts = 0
7
+
8
+ class << self
9
+ def start
10
+ self.config = Adhearsion.config[:punchblock]
11
+ connection_class = case (self.config.platform || :xmpp)
12
+ when :xmpp
13
+ ::Punchblock::Connection::XMPP
14
+ when :asterisk
15
+ ::Punchblock::Connection::Asterisk
16
+ end
17
+ connection_options = {
18
+ :username => self.config.username,
19
+ :password => self.config.password,
20
+ :connection_timeout => self.config.connection_timeout,
21
+ :host => self.config.host,
22
+ :port => self.config.port,
23
+ :root_domain => self.config.root_domain,
24
+ :calls_domain => self.config.calls_domain,
25
+ :mixers_domain => self.config.mixers_domain
26
+ }
27
+
28
+ connection = connection_class.new connection_options
29
+ self.client = ::Punchblock::Client.new :connection => connection
30
+
31
+ # Tell the Punchblock connection that we are ready to process calls.
32
+ Events.register_callback :after_initialization do
33
+ connection.ready!
34
+ end
35
+
36
+ # When a stop is requested, change our status to "Do Not Disturb"
37
+ # This should prevent the telephony engine from sending us any new calls.
38
+ Events.register_callback :stop_requested do
39
+ connection.not_ready!
40
+ end
41
+
42
+ # Make sure we stop everything when we shutdown
43
+ Events.register_callback :shutdown do
44
+ client.stop
45
+ end
46
+
47
+ # Handle events from Punchblock via events system
48
+ self.client.register_event_handler do |event|
49
+ Events.trigger :punchblock, event
50
+ end
51
+
52
+ Events.punchblock ::Punchblock::Connection::Connected do |event|
53
+ logger.info "Connected to Punchblock server"
54
+ self.attempts = 0
55
+ end
56
+
57
+ Events.punchblock ::Punchblock::Event::Offer do |offer|
58
+ dispatch_offer offer
59
+ end
60
+
61
+ Events.punchblock proc { |e| e.respond_to?(:source) }, :source do |event|
62
+ event.source.trigger_event_handler event
63
+ end
64
+
65
+ Events.punchblock proc { |e| e.respond_to?(:call_id) }, :call_id do |event|
66
+ dispatch_call_event event
67
+ end
68
+
69
+ connect
70
+ end
71
+
72
+ def connect
73
+ m = Mutex.new
74
+ blocker = ConditionVariable.new
75
+ Events.punchblock ::Punchblock::Connection::Connected do
76
+ m.synchronize { blocker.broadcast }
77
+ end
78
+
79
+ Adhearsion::Process.important_threads << Thread.new do
80
+ catching_standard_errors { connect_to_server }
81
+ end
82
+
83
+ # Wait for the connection to establish
84
+ m.synchronize { blocker.wait m }
85
+ end
86
+
87
+ def connect_to_server
88
+ begin
89
+ logger.info "Starting connection to server"
90
+ client.run
91
+ rescue ::Punchblock::DisconnectedError => e
92
+ # We only care about disconnects if the process is up or booting
93
+ if [:booting, :running].include? Adhearsion::Process.state_name
94
+ self.attempts += 1
95
+ Adhearsion::Process.reset unless Adhearsion::Process.state_name == :booting
96
+ logger.error "Connection lost. Attempting reconnect #{self.attempts} of #{self.config.reconnect_attempts}"
97
+ sleep self.config.reconnect_timer
98
+ retry unless self.attempts >= self.config.reconnect_attempts
99
+ logger.fatal "Connection retry attempts exceeded"
100
+ raise e
101
+ end
102
+ rescue ::Punchblock::ProtocolError => e
103
+ logger.fatal "The connection failed due to a protocol error: #{e.name}."
104
+ raise e
105
+ end
106
+ end
107
+
108
+ def dispatch_offer(offer)
109
+ catching_standard_errors do
110
+ call = Adhearsion.active_calls.from_offer offer
111
+ case Adhearsion::Process.state_name
112
+ when :booting, :rejecting
113
+ call.reject :decline
114
+ when :running
115
+ dispatcher = Adhearsion.router.handle call
116
+ dispatcher.call call
117
+ else
118
+ call.reject :error
119
+ end
120
+ end
121
+ end
122
+
123
+ def dispatch_call_event(event, latch = nil)
124
+ if call = Adhearsion.active_calls.find(event.call_id)
125
+ logger.debug "Event received for call #{call.id}: #{event.inspect}"
126
+ Thread.new do
127
+ call << event
128
+ latch.countdown! if latch
129
+ end
130
+ else
131
+ logger.error "Event received for inactive call #{event.call_id}: #{event.inspect}"
132
+ end
133
+ end
134
+ end
135
+ end # Punchblock
136
+ end # Plugin
137
+ end # Adhearsion
@@ -0,0 +1,30 @@
1
+ module Adhearsion
2
+ class Router
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Route
6
+
7
+ attr_reader :routes
8
+
9
+ def initialize(&block)
10
+ @routes = []
11
+ instance_exec &block
12
+ end
13
+
14
+ def route(*args, &block)
15
+ Route.new(*args, &block).tap do |route|
16
+ @routes << route
17
+ end
18
+ end
19
+
20
+ def match(call)
21
+ @routes.find { |route| route.match? call }
22
+ end
23
+
24
+ def handle(call)
25
+ return unless route = match(call)
26
+ logger.debug "Call #{call.id} passing through router matched route #{route}"
27
+ route.dispatcher
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ module Adhearsion
2
+ class Router
3
+ class Route
4
+ include HasGuardedHandlers
5
+
6
+ attr_reader :name, :target, :guards
7
+
8
+ def initialize(name, target = nil, *guards, &block)
9
+ @name = name
10
+ if block
11
+ @target, @guards = block, ([target] + guards)
12
+ else
13
+ @target, @guards = target, guards
14
+ end
15
+ @guards.compact!
16
+ end
17
+
18
+ def match?(call)
19
+ !guarded? guards, call
20
+ end
21
+
22
+ def dispatcher
23
+ @dispatcher ||= lambda do |call|
24
+ controller = if target.respond_to?(:call)
25
+ DialplanController.new(call).tap do |controller|
26
+ controller.dialplan = target
27
+ end
28
+ else
29
+ target.new call
30
+ end
31
+
32
+ call.execute_controller controller
33
+ end
34
+ end
35
+
36
+ def inspect
37
+ "#<#{self.class}:#{object_id} name=#{name} target=#{target} guards=#{guards}>"
38
+ end
39
+ alias :to_s :inspect
40
+ end
41
+ end
42
+ end
@@ -19,8 +19,8 @@ module Adhearsion
19
19
  # could not chdir, no problem just return
20
20
  end
21
21
 
22
- def self.in_ahn_application?
23
- File.exists? SCRIPT_AHN
22
+ def self.in_ahn_application?(path = '.')
23
+ Dir.chdir(path) { File.exists? SCRIPT_AHN }
24
24
  end
25
25
 
26
26
  def self.in_ahn_application_subdirectory?(path = Pathname.new(Dir.pwd))
@@ -1,16 +1,21 @@
1
- require 'rake/testtask'
2
1
  require 'adhearsion'
3
- require 'adhearsion/tasks/components'
4
- require 'adhearsion/tasks/database'
5
- require 'adhearsion/tasks/testing'
6
- require 'adhearsion/tasks/generating'
7
- require 'adhearsion/tasks/lint'
8
- require 'adhearsion/tasks/deprecations'
2
+
3
+ %w<
4
+ configuration
5
+ testing
6
+ plugins
7
+ >.each do |file|
8
+ require "adhearsion/tasks/#{file}"
9
+ end
10
+
11
+ Adhearsion::Plugin.load_tasks
12
+
13
+ puts "\nAdhearsion configured environment: #{Adhearsion.config.platform.environment}\n" unless ARGV.empty?
9
14
 
10
15
  namespace :adhearsion do
11
- desc "Dump useful information about this application's adhearsion environment"
16
+ desc "Dump useful information about this application's Adhearsion environment"
12
17
  task :about do
13
- puts "Adhearsion version: #{Adhearsion::VERSION::STRING}"
18
+ puts "Adhearsion version: #{Adhearsion::VERSION}"
14
19
  end
15
20
  end
16
21