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.
- data/.gitignore +17 -10
- data/CHANGELOG.md +273 -0
- data/Gemfile +1 -1
- data/Guardfile +17 -0
- data/README.markdown +61 -9
- data/Rakefile +16 -48
- data/adhearsion.gemspec +21 -7
- data/bin/ahn +3 -1
- data/cucumber.yml +4 -0
- data/features/app_generator.feature +42 -0
- data/features/cli.feature +108 -0
- data/features/step_definitions/app_generator_steps.rb +6 -0
- data/features/step_definitions/cli_steps.rb +74 -0
- data/features/support/aruba_helper.rb +22 -0
- data/features/support/env.rb +37 -0
- data/features/support/utils.rb +8 -0
- data/lib/adhearsion.rb +85 -41
- data/lib/adhearsion/call.rb +176 -0
- data/lib/adhearsion/call_controller.rb +134 -0
- data/lib/adhearsion/call_controller/dial.rb +70 -0
- data/lib/adhearsion/call_controller/input.rb +173 -0
- data/lib/adhearsion/call_controller/menu.rb +124 -0
- data/lib/adhearsion/call_controller/output.rb +267 -0
- data/lib/adhearsion/call_controller/record.rb +42 -0
- data/lib/adhearsion/call_controller/utility.rb +60 -0
- data/lib/adhearsion/calls.rb +81 -0
- data/lib/adhearsion/cli.rb +1 -3
- data/lib/adhearsion/cli_commands.rb +142 -0
- data/lib/adhearsion/configuration.rb +149 -0
- data/lib/adhearsion/console.rb +19 -8
- data/lib/adhearsion/dialplan_controller.rb +9 -0
- data/lib/adhearsion/events.rb +84 -0
- data/lib/adhearsion/foundation/all.rb +0 -7
- data/lib/adhearsion/foundation/custom_daemonizer.rb +4 -6
- data/lib/adhearsion/foundation/exception_handler.rb +9 -0
- data/lib/adhearsion/foundation/object.rb +26 -8
- data/lib/adhearsion/foundation/synchronized_hash.rb +3 -6
- data/lib/adhearsion/foundation/thread_safety.rb +17 -1
- data/lib/adhearsion/generators/app/app_generator.rb +4 -13
- data/lib/adhearsion/generators/app/templates/Gemfile +10 -5
- data/lib/adhearsion/generators/app/templates/Procfile +1 -0
- data/lib/adhearsion/generators/app/templates/README.md +28 -0
- data/lib/adhearsion/generators/app/templates/config/adhearsion.rb +41 -0
- data/lib/adhearsion/generators/app/templates/{components/simon_game → lib}/simon_game.rb +6 -18
- data/lib/adhearsion/generators/app/templates/script/ahn +2 -2
- data/lib/adhearsion/initializer.rb +151 -293
- data/lib/adhearsion/initializer/logging.rb +33 -0
- data/lib/adhearsion/logging.rb +65 -69
- data/lib/adhearsion/menu_dsl.rb +15 -0
- data/lib/adhearsion/menu_dsl/calculated_match.rb +39 -0
- data/lib/adhearsion/menu_dsl/calculated_match_collection.rb +41 -0
- data/lib/adhearsion/menu_dsl/fixnum_match_calculator.rb +18 -0
- data/lib/adhearsion/menu_dsl/match_calculator.rb +36 -0
- data/lib/adhearsion/{voip/menu_state_machine/menu_class.rb → menu_dsl/menu.rb} +38 -40
- data/lib/adhearsion/menu_dsl/menu_builder.rb +69 -0
- data/lib/adhearsion/menu_dsl/range_match_calculator.rb +55 -0
- data/lib/adhearsion/menu_dsl/string_match_calculator.rb +21 -0
- data/lib/adhearsion/outbound_call.rb +64 -0
- data/lib/adhearsion/plugin.rb +319 -0
- data/lib/adhearsion/plugin/collection.rb +19 -0
- data/lib/adhearsion/plugin/initializer.rb +37 -0
- data/lib/adhearsion/plugin/methods_container.rb +6 -0
- data/lib/adhearsion/process.rb +94 -0
- data/lib/adhearsion/punchblock_plugin.rb +29 -0
- data/lib/adhearsion/punchblock_plugin/initializer.rb +137 -0
- data/lib/adhearsion/router.rb +30 -0
- data/lib/adhearsion/router/route.rb +42 -0
- data/lib/adhearsion/script_ahn_loader.rb +2 -2
- data/lib/adhearsion/tasks.rb +14 -9
- data/lib/adhearsion/tasks/configuration.rb +26 -0
- data/lib/adhearsion/tasks/plugins.rb +17 -0
- data/lib/adhearsion/version.rb +8 -14
- data/spec/adhearsion/call_controller/dial_spec.rb +138 -0
- data/spec/adhearsion/call_controller/input_spec.rb +278 -0
- data/spec/adhearsion/call_controller/menu_spec.rb +120 -0
- data/spec/adhearsion/call_controller/output_spec.rb +466 -0
- data/spec/adhearsion/call_controller/record_spec.rb +125 -0
- data/spec/adhearsion/call_controller_spec.rb +395 -0
- data/spec/adhearsion/call_spec.rb +438 -0
- data/spec/adhearsion/calls_spec.rb +47 -0
- data/spec/adhearsion/configuration_spec.rb +308 -0
- data/spec/adhearsion/dialplan_controller_spec.rb +26 -0
- data/spec/adhearsion/events_spec.rb +112 -0
- data/spec/adhearsion/initializer/logging_spec.rb +58 -0
- data/spec/adhearsion/initializer_spec.rb +209 -122
- data/spec/adhearsion/logging_spec.rb +58 -47
- data/spec/adhearsion/menu_dsl/calculated_match_collection_spec.rb +56 -0
- data/spec/adhearsion/menu_dsl/calculated_match_spec.rb +57 -0
- data/spec/adhearsion/menu_dsl/fixnum_match_calculator_spec.rb +33 -0
- data/spec/adhearsion/menu_dsl/match_calculator_spec.rb +13 -0
- data/spec/adhearsion/menu_dsl/menu_builder_spec.rb +118 -0
- data/spec/adhearsion/menu_dsl/menu_spec.rb +210 -0
- data/spec/adhearsion/menu_dsl/range_match_calculator_spec.rb +28 -0
- data/spec/adhearsion/menu_dsl/string_match_calculator_spec.rb +36 -0
- data/spec/adhearsion/menu_dsl_spec.rb +12 -0
- data/spec/adhearsion/outbound_call_spec.rb +174 -0
- data/spec/adhearsion/plugin_spec.rb +489 -0
- data/spec/adhearsion/process_spec.rb +34 -0
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +294 -0
- data/spec/adhearsion/router/route_spec.rb +99 -0
- data/spec/adhearsion/router_spec.rb +106 -0
- data/spec/adhearsion_spec.rb +46 -0
- data/spec/spec_helper.rb +14 -14
- data/spec/support/call_controller_test_helpers.rb +48 -0
- data/spec/support/initializer_stubs.rb +8 -13
- data/spec/support/punchblock_mocks.rb +6 -0
- metadata +255 -253
- data/CHANGELOG +0 -174
- data/bin/ahnctl +0 -68
- data/bin/jahn +0 -43
- data/examples/asterisk_manager_interface/standalone.rb +0 -51
- data/lib/adhearsion/commands.rb +0 -302
- data/lib/adhearsion/component_manager.rb +0 -278
- data/lib/adhearsion/component_manager/component_tester.rb +0 -54
- data/lib/adhearsion/component_manager/spec_framework.rb +0 -18
- data/lib/adhearsion/events_support.rb +0 -65
- data/lib/adhearsion/foundation/blank_slate.rb +0 -3
- data/lib/adhearsion/foundation/event_socket.rb +0 -205
- data/lib/adhearsion/foundation/future_resource.rb +0 -36
- data/lib/adhearsion/foundation/metaprogramming.rb +0 -17
- data/lib/adhearsion/foundation/numeric.rb +0 -13
- data/lib/adhearsion/foundation/pseudo_guid.rb +0 -10
- data/lib/adhearsion/foundation/relationship_properties.rb +0 -42
- data/lib/adhearsion/foundation/string.rb +0 -26
- data/lib/adhearsion/generators/app/templates/.ahnrc +0 -34
- data/lib/adhearsion/generators/app/templates/README +0 -8
- data/lib/adhearsion/generators/app/templates/components/ami_remote/ami_remote.rb +0 -15
- data/lib/adhearsion/generators/app/templates/components/disabled/HOW_TO_ENABLE +0 -7
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/README.markdown +0 -47
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.rb +0 -34
- data/lib/adhearsion/generators/app/templates/components/disabled/stomp_gateway/stomp_gateway.yml +0 -12
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/README.markdown +0 -3
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.rb +0 -11
- data/lib/adhearsion/generators/app/templates/components/disabled/xmpp_gateway/xmpp_gateway.yml +0 -0
- data/lib/adhearsion/generators/app/templates/config/startup.rb +0 -81
- data/lib/adhearsion/generators/app/templates/dialplan.rb +0 -3
- data/lib/adhearsion/generators/app/templates/events.rb +0 -33
- data/lib/adhearsion/host_definitions.rb +0 -67
- data/lib/adhearsion/initializer/asterisk.rb +0 -86
- data/lib/adhearsion/initializer/configuration.rb +0 -324
- data/lib/adhearsion/initializer/database.rb +0 -60
- data/lib/adhearsion/initializer/drb.rb +0 -31
- data/lib/adhearsion/initializer/freeswitch.rb +0 -22
- data/lib/adhearsion/initializer/ldap.rb +0 -57
- data/lib/adhearsion/initializer/rails.rb +0 -41
- data/lib/adhearsion/initializer/xmpp.rb +0 -42
- data/lib/adhearsion/tasks/components.rb +0 -32
- data/lib/adhearsion/tasks/database.rb +0 -5
- data/lib/adhearsion/tasks/deprecations.rb +0 -59
- data/lib/adhearsion/tasks/generating.rb +0 -20
- data/lib/adhearsion/tasks/lint.rb +0 -4
- data/lib/adhearsion/voip/asterisk.rb +0 -4
- data/lib/adhearsion/voip/asterisk/agi_server.rb +0 -121
- data/lib/adhearsion/voip/asterisk/commands.rb +0 -1966
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +0 -140
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +0 -102
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +0 -250
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +0 -240
- data/lib/adhearsion/voip/asterisk/config_manager.rb +0 -64
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -697
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +0 -1681
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +0 -341
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +0 -78
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +0 -87
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +0 -80
- data/lib/adhearsion/voip/call.rb +0 -521
- data/lib/adhearsion/voip/call_routing.rb +0 -64
- data/lib/adhearsion/voip/commands.rb +0 -17
- data/lib/adhearsion/voip/constants.rb +0 -39
- data/lib/adhearsion/voip/conveniences.rb +0 -18
- data/lib/adhearsion/voip/dial_plan.rb +0 -252
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +0 -151
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +0 -37
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +0 -27
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +0 -124
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +0 -69
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +0 -16
- data/lib/adhearsion/voip/dsl/numerical_string.rb +0 -128
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +0 -48
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +0 -58
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +0 -129
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +0 -38
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +0 -195
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +0 -80
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +0 -123
- data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +0 -57
- data/lib/adhearsion/xmpp/connection.rb +0 -61
- data/lib/theatre.rb +0 -147
- data/lib/theatre/README.markdown +0 -64
- data/lib/theatre/callback_definition_loader.rb +0 -86
- data/lib/theatre/guid.rb +0 -23
- data/lib/theatre/invocation.rb +0 -131
- data/lib/theatre/namespace_manager.rb +0 -153
- data/lib/theatre/version.rb +0 -2
- data/spec/adhearsion/cli_spec.rb +0 -306
- data/spec/adhearsion/component_manager_spec.rb +0 -292
- data/spec/adhearsion/constants_spec.rb +0 -8
- data/spec/adhearsion/drb_spec.rb +0 -65
- data/spec/adhearsion/fixtures/dialplan.rb +0 -3
- data/spec/adhearsion/foundation/event_socket_spec.rb +0 -168
- data/spec/adhearsion/host_definitions_spec.rb +0 -79
- data/spec/adhearsion/initializer/configuration_spec.rb +0 -291
- data/spec/adhearsion/initializer/loading_spec.rb +0 -154
- data/spec/adhearsion/initializer/paths_spec.rb +0 -74
- data/spec/adhearsion/relationship_properties_spec.rb +0 -54
- data/spec/adhearsion/voip/asterisk/agi_server_spec.rb +0 -473
- data/spec/adhearsion/voip/asterisk/ami/ami_spec.rb +0 -550
- data/spec/adhearsion/voip/asterisk/ami/lexer/ami_fixtures.yml +0 -30
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story +0 -291
- data/spec/adhearsion/voip/asterisk/ami/lexer/lexer_story.rb +0 -241
- data/spec/adhearsion/voip/asterisk/ami/lexer/story_helper.rb +0 -124
- data/spec/adhearsion/voip/asterisk/commands_spec.rb +0 -3241
- data/spec/adhearsion/voip/asterisk/config_file_generators/agents_spec.rb +0 -251
- data/spec/adhearsion/voip/asterisk/config_file_generators/queues_spec.rb +0 -323
- data/spec/adhearsion/voip/asterisk/config_file_generators/voicemail_spec.rb +0 -306
- data/spec/adhearsion/voip/asterisk/config_manager_spec.rb +0 -127
- data/spec/adhearsion/voip/asterisk/menu_command/calculated_match_spec.rb +0 -109
- data/spec/adhearsion/voip/asterisk/menu_command/matchers_spec.rb +0 -97
- data/spec/adhearsion/voip/call_routing_spec.rb +0 -125
- data/spec/adhearsion/voip/dialplan_manager_spec.rb +0 -468
- data/spec/adhearsion/voip/dsl/dialing_dsl_spec.rb +0 -270
- data/spec/adhearsion/voip/dsl/dispatcher_spec.rb +0 -82
- data/spec/adhearsion/voip/dsl/dispatcher_spec_helper.rb +0 -45
- data/spec/adhearsion/voip/dsl/parser_spec.rb +0 -69
- data/spec/adhearsion/voip/freeswitch/basic_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/inbound_connection_manager_spec.rb +0 -39
- data/spec/adhearsion/voip/freeswitch/oes_server_spec.rb +0 -9
- data/spec/adhearsion/voip/numerical_string_spec.rb +0 -61
- data/spec/adhearsion/voip/phone_number_spec.rb +0 -45
- data/spec/support/the_following_code.rb +0 -3
- data/spec/theatre/dsl_examples/simple_before_call.rb +0 -7
- data/spec/theatre/dsl_spec.rb +0 -69
- data/spec/theatre/invocation_spec.rb +0 -182
- data/spec/theatre/namespace_spec.rb +0 -125
- data/spec/theatre/spec_helper_spec.rb +0 -28
- 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,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))
|
data/lib/adhearsion/tasks.rb
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
require 'rake/testtask'
|
|
2
1
|
require 'adhearsion'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
16
|
+
desc "Dump useful information about this application's Adhearsion environment"
|
|
12
17
|
task :about do
|
|
13
|
-
puts "Adhearsion version: #{Adhearsion::VERSION
|
|
18
|
+
puts "Adhearsion version: #{Adhearsion::VERSION}"
|
|
14
19
|
end
|
|
15
20
|
end
|
|
16
21
|
|