adhearsion 1.2.6 → 2.0.0.alpha1

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