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
@@ -1,278 +0,0 @@
1
- module Adhearsion
2
- module Components
3
-
4
- mattr_accessor :component_manager
5
-
6
- class ConfigurationError < Exception; end
7
-
8
- class ComponentManager
9
-
10
- class << self
11
-
12
- def scopes_valid?(*scopes)
13
- unrecognized_scopes = (scopes.flatten - SCOPE_NAMES).map(&:inspect)
14
- raise ArgumentError, "Unrecognized scopes #{unrecognized_scopes.to_sentence}" if unrecognized_scopes.any?
15
- true
16
- end
17
-
18
- end
19
-
20
- SCOPE_NAMES = [:dialplan, :events, :generators, :rpc, :global]
21
-
22
- attr_reader :scopes, :lazy_config_loader
23
- def initialize(path_to_container_directory)
24
- @path_to_container_directory = path_to_container_directory
25
- @scopes = SCOPE_NAMES.inject({}) do |scopes, name|
26
- scopes[name] = Module.new
27
- scopes
28
- end
29
- @lazy_config_loader = LazyConfigLoader.new(self)
30
- end
31
-
32
- ##
33
- # Includes the anonymous Module created for the :global scope in Object, making its methods globally accessible.
34
- #
35
- def globalize_global_scope!
36
- Object.send :include, @scopes[:global]
37
- end
38
-
39
- def load_components
40
- components = Dir.glob(File.join(@path_to_container_directory + "/*")).select do |path|
41
- File.directory?(path)
42
- end
43
- components.map! { |path| File.basename path }
44
- components.each do |component|
45
- next if component == "disabled"
46
- component_file = File.join(@path_to_container_directory, component, 'lib', component + ".rb")
47
- if File.exists? component_file
48
- load_file component_file
49
- next
50
- end
51
-
52
- # Try the old-style components/<component>/<component>.rb
53
- component_file = File.join(@path_to_container_directory, component, component + ".rb")
54
- if File.exists? component_file
55
- load_file component_file
56
- else
57
- ahn_log.warn "Component directory does not contain a matching .rb file! Was expecting #{component_file.inspect}"
58
- end
59
- end
60
-
61
- # Load configured system- or gem-provided components
62
- AHN_CONFIG.components_to_load.each do |component|
63
- require component
64
- end
65
-
66
- end
67
-
68
- ##
69
- # Loads the configuration file for a given component name.
70
- #
71
- # @return [Hash] The loaded YAML for the given component name. An empty Hash if no YAML file exists.
72
- #
73
- def configuration_for_component_named(component_name)
74
- # Look for configuration in #{AHN_ROOT}/config/components first
75
- # Look for configuration in #{AHN_ROOT}/components/#{component_name}/config next
76
- # Next try the local app component directory
77
- %W{
78
- #{AHN_ROOT}/config/components/#{component_name}.yml
79
- #{AHN_ROOT}/components/#{component_name}/config/#{component_name}.yml
80
- #{File.join @path_to_container_directory, component_name, "#{component_name}.yml"}
81
- }.each do |filename|
82
- return YAML.load_file filename if File.exists?(filename)
83
- end
84
-
85
- # Nothing found? Return an empty hash
86
- ahn_log.warn "No configuration found for requested component #{component_name}"
87
- {}
88
- end
89
-
90
- def extend_object_with(object, *scopes)
91
- raise ArgumentError, "Must supply at least one scope!" if scopes.empty?
92
-
93
- self.class.scopes_valid? scopes
94
-
95
- scopes.each do |scope|
96
- methods = @scopes[scope]
97
- if object.kind_of?(Module)
98
- object.send :include, methods
99
- else
100
- object.extend methods
101
- end
102
- end
103
- object
104
- end
105
-
106
- def load_code(code)
107
- load_container ComponentDefinitionContainer.load_code(code)
108
- end
109
-
110
- def load_file(filename)
111
- load_container ComponentDefinitionContainer.load_file(filename)
112
- end
113
-
114
- def require(filename)
115
- load_container ComponentDefinitionContainer.require(filename)
116
- end
117
-
118
- protected
119
-
120
- def load_container(container)
121
- container.constants.each do |constant_name|
122
- constant_value = container.const_get(constant_name)
123
- Object.const_set(constant_name, constant_value)
124
- end
125
- metadata = container.metaclass.send(:instance_variable_get, :@metadata)
126
- metadata[:initialization_block].call if metadata[:initialization_block]
127
-
128
- self.class.scopes_valid? metadata[:scopes].keys
129
-
130
- metadata[:scopes].each_pair do |scope, method_definition_blocks|
131
- method_definition_blocks.each do |method_definition_block|
132
- @scopes[scope].module_eval(&method_definition_block)
133
- end
134
- end
135
- container
136
- rescue StandardError => e
137
- # Non-fatal errors
138
- Events.trigger(['exception'], e)
139
- rescue Exception => e
140
- # Fatal errors. Log them and keep passing them upward
141
- Events.trigger(['exception'], e)
142
- raise e
143
- end
144
-
145
- class ComponentDefinitionContainer < Module
146
-
147
- class << self
148
- def load_code(code)
149
- new.tap do |instance|
150
- instance.module_eval code
151
- end
152
- end
153
-
154
- def load_file(filename)
155
- new.tap do |instance|
156
- instance.module_eval File.read(filename), filename
157
- end
158
- end
159
-
160
- def require(filename)
161
- filename = filename + ".rb" if !(filename =~ /\.rb$/)
162
- begin
163
- # Try loading the exact filename first
164
- load_file(filename)
165
- rescue LoadError, Errno::ENOENT
166
- end
167
-
168
- # Next try Rubygems
169
- filepath = get_gem_path_for(filename)
170
- return load_file(filepath) if !filepath.nil?
171
-
172
- # Finally try the system search path
173
- filepath = get_system_path_for(filename)
174
- return load_file(filepath) if !filepath.nil?
175
-
176
- # Raise a LoadError exception if the file is still not found
177
- raise LoadError, "File not found: #{filename}"
178
- end
179
-
180
- end
181
-
182
- def initialize(&block)
183
- # Hide our instance variables in the singleton class
184
- metadata = {}
185
- metaclass.send(:instance_variable_set, :@metadata, metadata)
186
-
187
- metadata[:scopes] = ComponentManager::SCOPE_NAMES.inject({}) do |scopes, name|
188
- scopes[name] = []
189
- scopes
190
- end
191
-
192
- super
193
-
194
- meta_def(:initialize) { raise "This object has already been instantiated. Are you sure you didn't mean initialization()?" }
195
- end
196
-
197
- def methods_for(*scopes, &block)
198
- raise ArgumentError if scopes.empty?
199
-
200
- ComponentManager.scopes_valid? scopes
201
-
202
- metadata = metaclass.send(:instance_variable_get, :@metadata)
203
- scopes.each { |scope| metadata[:scopes][scope] << block }
204
- end
205
-
206
- def initialization(&block)
207
- # Raise an exception if the initialization block has already been set
208
- metadata = metaclass.send(:instance_variable_get, :@metadata)
209
- if metadata[:initialization_block]
210
- raise "You should only have one initialization() block!"
211
- else
212
- metadata[:initialization_block] = block
213
- end
214
- end
215
- alias initialisation initialization
216
-
217
- protected
218
-
219
- class << self
220
- def self.method_added(method_name)
221
- @methods ||= []
222
- @methods << method_name
223
- end
224
-
225
- def get_gem_path_for(filename)
226
- # Look for component files provided by rubygems
227
- spec = Gem.searcher.find(filename)
228
- return nil if spec.nil?
229
- File.join(spec.full_gem_path, spec.require_path, filename)
230
- rescue NameError
231
- # In case Rubygems are not available
232
- nil
233
- end
234
-
235
- def get_system_path_for(filename)
236
- $:.each do |path|
237
- filepath = File.join(path, filename)
238
- return filepath if File.exists?(filepath)
239
- end
240
-
241
- # Not found? Return nil
242
- return nil
243
- end
244
- end
245
-
246
- end
247
-
248
- class ComponentMethodDefinitionContainer < Module
249
- class << self
250
- def method_added(method_name)
251
- @methods ||= []
252
- @methods << method_name
253
- end
254
- end
255
-
256
- attr_reader :scopes
257
- def initialize(*scopes, &block)
258
- @scopes = []
259
- super(&block)
260
- end
261
-
262
- end
263
-
264
- class LazyConfigLoader
265
- def initialize(component_manager)
266
- @component_manager = component_manager
267
- end
268
-
269
- def method_missing(component_name)
270
- config = @component_manager.configuration_for_component_named(component_name.to_s)
271
- (class << self; self; end).send(:define_method, component_name) { config }
272
- config
273
- end
274
- end
275
-
276
- end
277
- end
278
- end
@@ -1,54 +0,0 @@
1
- module ComponentTester
2
-
3
- class << self
4
-
5
- ##
6
- #
7
- #
8
- # @return [Module] an anonymous module which includes the ComponentTester module.
9
- #
10
- def new(component_name, component_directory, main_file = nil)
11
- component_directory = File.expand_path component_directory
12
- main_file ||= "/#{component_name}/#{component_name}.rb"
13
- main_file.insert 0, component_directory
14
-
15
- component_manager = Adhearsion::Components::ComponentManager.new(component_directory)
16
- component_module = Adhearsion::Components::ComponentManager::ComponentDefinitionContainer.load_file main_file
17
-
18
- Module.new do
19
-
20
- extend ComponentTester
21
-
22
- (class << self; self; end).send(:define_method, :component_manager) { component_manager }
23
- (class << self; self; end).send(:define_method, :component_name) { component_name }
24
- (class << self; self; end).send(:define_method, :component_module) { component_module }
25
- (class << self; self; end).send(:define_method, :component_directory) { component_directory }
26
-
27
-
28
- define_method(:component_manager) { component_manager }
29
- define_method(:component_name) { component_name }
30
- define_method(:component_module) { component_module }
31
- define_method(:component_directory) { component_directory }
32
-
33
- def self.const_missing(name)
34
- component_module.const_get name
35
- end
36
-
37
- end
38
- end
39
- end
40
-
41
- def helper_method(name)
42
- Object.new.extend(component_module).method(name)
43
- end
44
-
45
- def config
46
- component_manager.configuration_for_component_named component_name
47
- end
48
-
49
- def initialize!
50
- metadata = component_module.metaclass.send(:instance_variable_get, :@metadata)
51
- metadata[:initialization_block].call if metadata && metadata[:initialization_block].kind_of?(Proc)
52
- end
53
-
54
- end
@@ -1,18 +0,0 @@
1
- require 'adhearsion/component_manager/component_tester'
2
- begin
3
- require 'rspec'
4
- rescue LoadError
5
- abort "You do not have the 'rspec' gem installed! You must install it to continue.\n\nsudo gem install rspec\n\n"
6
- end
7
-
8
- module ComponentConfigurationSpecHelper
9
- def mock_component_config_with(new_config)
10
- Object.send(:remove_const, :COMPONENTS) rescue nil
11
- Object.send(:const_set, :COMPONENTS, OpenStruct.new(new_config))
12
- end
13
- end
14
-
15
- RSpec.configure do |config|
16
- config.mock_with :rspec
17
- config.include ComponentConfigurationSpecHelper
18
- end
@@ -1,65 +0,0 @@
1
- require 'theatre'
2
-
3
- module Adhearsion
4
- module Events
5
-
6
- DEFAULT_FRAMEWORK_EVENT_NAMESPACES = %w[
7
- /after_initialized
8
- /shutdown
9
- /exception
10
- /asterisk/manager_interface
11
- /asterisk/before_call
12
- /asterisk/after_call
13
- /asterisk/hungup_call
14
- /asterisk/failed_call
15
- ]
16
-
17
- class << self
18
-
19
- def framework_theatre
20
- defined?(@@framework_theatre) ? @@framework_theatre : reinitialize_theatre!
21
- end
22
-
23
- def trigger(*args)
24
- framework_theatre.trigger(*args)
25
- end
26
-
27
- def trigger_immediately(*args)
28
- framework_theatre.trigger_immediately(*args)
29
- end
30
-
31
- def reinitialize_theatre!
32
- @@framework_theatre.gracefully_stop! if defined? @@framework_theatre
33
- rescue
34
- # Recover and reinitalize
35
- ensure
36
- # TODO: Extract number of threads to use from AHN_CONFIG
37
- @@framework_theatre = Theatre::Theatre.new
38
- DEFAULT_FRAMEWORK_EVENT_NAMESPACES.each do |namespace|
39
- register_namespace_name namespace
40
- end
41
- return @@framework_theatre
42
- end
43
-
44
- def register_namespace_name(name)
45
- framework_theatre.register_namespace_name name
46
- end
47
-
48
- def stop!
49
- Events.trigger :shutdown
50
- framework_theatre.graceful_stop!
51
- framework_theatre.join
52
- end
53
-
54
- def register_callback(namespace, block_arg=nil, &method_block)
55
- raise ArgumentError, "Cannot supply two blocks!" if block_arg && block_given?
56
- block = method_block || block_arg
57
- raise ArgumentError, "Must supply a callback!" unless block
58
-
59
- framework_theatre.register_callback_at_namespace(namespace, block)
60
- end
61
-
62
- end
63
-
64
- end
65
- end
@@ -1,3 +0,0 @@
1
- class BlankSlate
2
- (instance_methods.map{|m| m.to_sym} - [:instance_eval, :object_id]).each { |m| undef_method m unless m.to_s =~ /^__/ }
3
- end
@@ -1,205 +0,0 @@
1
- ##
2
- # EventSocket is a small abstraction of TCPSocket which causes it to behave much like an EventMachine Connection object for
3
- # the sake of better testability. The EventMachine Connection paradigm (as well as other networking libraries such as the
4
- # Objective-C HTTP library) uses callbacks to signal different stages of a socket's lifecycle.
5
- #
6
- # A handler can be registered in one of two ways: through registrations on an object yielded by the constructor or
7
- # pre-defined on the object given as a constructor parameter. Below is an example definition which uses the block way:
8
- #
9
- # EventSocket.new do |handler|
10
- # def handler.receive_data(data)
11
- # # Do something here
12
- # end
13
- # def handler.disconnected
14
- # # Do something here
15
- # end
16
- # def handler.connected
17
- # # Do something here
18
- # end
19
- # end
20
- #
21
- # Note: this is also a valid way of defining block callbacks:
22
- #
23
- # EventSocket.new do |handler|
24
- # handler.receive_data { |data| do_something }
25
- # handler.disconnected { do_something }
26
- # handler.connected { do_something }
27
- # end
28
- #
29
- # and here is an example of using a handler object:
30
- #
31
- # class MyCallbackHandler
32
- # def receive_data(data) end
33
- # def connected() end
34
- # def disconnected() end
35
- # end
36
- # EventSocket.new(MyCallbackHandler.new)
37
- #
38
- # If you wish to ask the EventSocket what state it is in, you can call the Thread-safe EventSocket#state method. The
39
- # supported states are:
40
- #
41
- # - :new
42
- # - :connected
43
- # - :stopped
44
- # - :connection_dropped
45
- #
46
- # Note: the EventSocket's state will be changed before these callbacks are executed. For example, if your "connected"
47
- # callback queried its own EventSocket for its state, it will have already transitioned to the connected() state.
48
- #
49
- # Warning: If an exception occurs in your EventSocket callbacks, they will be "eaten" and never bubbled up the call stack.
50
- # You should always wrap your callbacks in a begin/rescue clause and handle exceptions explicitly.
51
- #
52
- require "thread"
53
- require "socket"
54
-
55
- class EventSocket
56
-
57
- class << self
58
-
59
- ##
60
- # Creates and returns a connected EventSocket instance.
61
- #
62
- def connect(*args, &block)
63
- instance = new(*args, &block)
64
- instance.connect!
65
- instance
66
- end
67
- end
68
-
69
- MAX_CHUNK_SIZE = 256 * 1024
70
-
71
- def initialize(host, port, handler=nil, &block)
72
- raise ArgumentError, "Cannot supply both a handler object and a block" if handler && block_given?
73
- raise ArgumentError, "Must supply either a handler object or a block" if !handler && !block_given?
74
-
75
- @state_lock = Mutex.new
76
- @host = host
77
- @port = port
78
-
79
- @state = :new
80
- @handler = handler || new_handler_from_block(&block)
81
- end
82
-
83
- def state
84
- @state_lock.synchronize { @state }
85
- end
86
-
87
- def connect!
88
- @state_lock.synchronize do
89
- if @state.equal? :connected
90
- raise ConnectionError, "Already connected!"
91
- else
92
- @socket = TCPSocket.new(@host, @port)
93
- @state = :connected
94
- end
95
- end
96
- @handler.connected rescue nil
97
- @reader_thread = spawn_reader_thread
98
- self
99
- rescue => error
100
- @state = :failed
101
- raise error
102
- end
103
-
104
- ##
105
- # Thread-safe implementation of write.
106
- #
107
- # @param [String] data Data to write
108
- #
109
- def send_data(data)
110
- # Note: TCPSocket#write is intrinsically Thread-safe
111
- @socket.write data
112
- rescue
113
- connection_dropped!
114
- end
115
- ##
116
- # Disconnects this EventSocket and sets the state to :stopped
117
- #
118
- def disconnect!
119
- @state_lock.synchronize do
120
- @socket.close rescue nil
121
- @state = :stopped
122
- end
123
- end
124
-
125
- ##
126
- # Joins the Thread which reads data off the socket.
127
- #
128
- def join
129
- @state_lock.synchronize do
130
- if @state.equal? :connected
131
- @reader_thread.join
132
- else
133
- nil
134
- end
135
- end
136
- end
137
-
138
- def receive_data(data)
139
- @handler.receive_data(data)
140
- end
141
-
142
- protected
143
-
144
- def connection_dropped!
145
- @state_lock.synchronize do
146
- unless @state.equal? :connection_dropped
147
- @socket.close rescue nil
148
- @state = :connection_dropped
149
- @handler.disconnected
150
- end
151
- end
152
- end
153
-
154
- def spawn_reader_thread
155
- Thread.new(&method(:reader_loop))
156
- end
157
-
158
- def reader_loop
159
- until state.equal? :stopped
160
- data = @socket.readpartial(MAX_CHUNK_SIZE)
161
- @handler.receive_data data
162
- end
163
- rescue EOFError
164
- connection_dropped!
165
- end
166
-
167
- def new_handler_from_block(&handler_block)
168
- handler = Object.new
169
- handler.metaclass.send :attr_accessor, :set_callbacks
170
- handler.metaclass.send :public, :set_callbacks, :set_callbacks=
171
- handler.set_callbacks = {:receive_data => false, :disconnected => false, :connected => false }
172
-
173
- def handler.receive_data(&block)
174
- self.metaclass.send(:remove_method, :receive_data)
175
- self.metaclass.send(:define_method, :receive_data) { |data| block.call data }
176
- set_callbacks[:receive_data] = true
177
- end
178
- def handler.connected(&block)
179
- self.metaclass.send(:remove_method, :connected)
180
- self.metaclass.send(:define_method, :connected) { block.call }
181
- set_callbacks[:connected] = true
182
- end
183
- def handler.disconnected(&block)
184
- self.metaclass.send(:remove_method, :disconnected)
185
- self.metaclass.send(:define_method, :disconnected) { block.call }
186
- set_callbacks[:disconnected] = true
187
- end
188
-
189
- def handler.singleton_method_added(name)
190
- set_callbacks[name.to_sym] = true
191
- end
192
-
193
- yield handler
194
-
195
- handler.set_callbacks.each_pair do |callback_name,was_set|
196
- handler.send(callback_name) {} unless was_set
197
- end
198
-
199
- handler
200
-
201
- end
202
-
203
- class ConnectionError < StandardError; end
204
-
205
- end