gz_activemessaging 0.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +40 -0
  3. data/Appraisals +19 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +87 -0
  6. data/README.md +27 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/activemessaging.gemspec +137 -0
  10. data/gemfiles/activesupport23.gemfile +10 -0
  11. data/gemfiles/activesupport23.gemfile.lock +51 -0
  12. data/gemfiles/activesupport30.gemfile +11 -0
  13. data/gemfiles/activesupport30.gemfile.lock +53 -0
  14. data/gemfiles/activesupport31.gemfile +11 -0
  15. data/gemfiles/activesupport31.gemfile.lock +55 -0
  16. data/gemfiles/activesupport32.gemfile +10 -0
  17. data/gemfiles/activesupport32.gemfile.lock +55 -0
  18. data/generators/a13g_test_harness/a13g_test_harness_generator.rb +19 -0
  19. data/generators/a13g_test_harness/templates/active_messaging_test.rhtml +13 -0
  20. data/generators/a13g_test_harness/templates/active_messaging_test_controller.rb +29 -0
  21. data/generators/a13g_test_harness/templates/index.rhtml +17 -0
  22. data/generators/filter/USAGE +0 -0
  23. data/generators/filter/filter_generator.rb +19 -0
  24. data/generators/filter/templates/filter.rb +12 -0
  25. data/generators/filter/templates/filter_test.rb +28 -0
  26. data/generators/processor/USAGE +8 -0
  27. data/generators/processor/processor_generator.rb +31 -0
  28. data/generators/processor/templates/application_processor.rb +18 -0
  29. data/generators/processor/templates/broker.yml +140 -0
  30. data/generators/processor/templates/jruby_poller +117 -0
  31. data/generators/processor/templates/messaging.rb +12 -0
  32. data/generators/processor/templates/poller +25 -0
  33. data/generators/processor/templates/poller.rb +26 -0
  34. data/generators/processor/templates/processor.rb +8 -0
  35. data/generators/processor/templates/processor_test.rb +20 -0
  36. data/generators/tracer/USAGE +8 -0
  37. data/generators/tracer/templates/controller.rb +14 -0
  38. data/generators/tracer/templates/helper.rb +2 -0
  39. data/generators/tracer/templates/index.rhtml +4 -0
  40. data/generators/tracer/templates/layout.rhtml +16 -0
  41. data/generators/tracer/templates/trace_processor.rb +100 -0
  42. data/generators/tracer/tracer_generator.rb +25 -0
  43. data/init.rb +1 -0
  44. data/lib/activemessaging.rb +133 -0
  45. data/lib/activemessaging/adapter.rb +20 -0
  46. data/lib/activemessaging/adapters/amqp.rb +215 -0
  47. data/lib/activemessaging/adapters/asqs.rb +487 -0
  48. data/lib/activemessaging/adapters/base.rb +71 -0
  49. data/lib/activemessaging/adapters/beanstalk.rb +88 -0
  50. data/lib/activemessaging/adapters/jms.rb +243 -0
  51. data/lib/activemessaging/adapters/reliable_msg.rb +186 -0
  52. data/lib/activemessaging/adapters/stomp.rb +212 -0
  53. data/lib/activemessaging/adapters/synch.rb +95 -0
  54. data/lib/activemessaging/adapters/test.rb +137 -0
  55. data/lib/activemessaging/adapters/wmq.rb +193 -0
  56. data/lib/activemessaging/base_message.rb +28 -0
  57. data/lib/activemessaging/filter.rb +29 -0
  58. data/lib/activemessaging/gateway.rb +429 -0
  59. data/lib/activemessaging/message_sender.rb +30 -0
  60. data/lib/activemessaging/named_base.rb +54 -0
  61. data/lib/activemessaging/processor.rb +44 -0
  62. data/lib/activemessaging/railtie.rb +26 -0
  63. data/lib/activemessaging/test_helper.rb +189 -0
  64. data/lib/activemessaging/threaded_poller.rb +234 -0
  65. data/lib/activemessaging/trace_filter.rb +34 -0
  66. data/lib/generators/active_messaging/install/USAGE +21 -0
  67. data/lib/generators/active_messaging/install/install_generator.rb +39 -0
  68. data/lib/generators/active_messaging/install/templates/application_processor.rb +18 -0
  69. data/lib/generators/active_messaging/install/templates/broker.yml +139 -0
  70. data/lib/generators/active_messaging/install/templates/poller +24 -0
  71. data/lib/generators/active_messaging/install/templates/poller.rb +22 -0
  72. data/lib/generators/active_messaging/install/templates/threaded_poller +46 -0
  73. data/lib/generators/active_messaging/processor/USAGE +2 -0
  74. data/lib/generators/active_messaging/processor/processor_generator.rb +39 -0
  75. data/lib/generators/active_messaging/processor/templates/messaging.rb +12 -0
  76. data/lib/generators/active_messaging/processor/templates/processor.rb +8 -0
  77. data/lib/generators/active_messaging/processor/templates/processor_spec.rb +24 -0
  78. data/lib/generators/active_messaging/processor/templates/processor_test.rb +20 -0
  79. data/lib/tasks/start_consumers.rake +8 -0
  80. data/poller.rb +14 -0
  81. data/test/all_tests.rb +10 -0
  82. data/test/app/config/broker.yml +4 -0
  83. data/test/asqs_test.rb +125 -0
  84. data/test/config_test.rb +42 -0
  85. data/test/filter_test.rb +131 -0
  86. data/test/gateway_test.rb +220 -0
  87. data/test/jms_test.rb +64 -0
  88. data/test/reliable_msg_test.rb +83 -0
  89. data/test/stomp_test.rb +168 -0
  90. data/test/test_helper.rb +36 -0
  91. data/test/tracer_test.rb +57 -0
  92. metadata +202 -0
@@ -0,0 +1,34 @@
1
+ class TraceFilter< ActiveMessaging::Filter
2
+ include ActiveMessaging::MessageSender
3
+
4
+ def initialize(options)
5
+ @queue = options[:queue]
6
+ TraceFilter.publishes_to @queue
7
+ end
8
+
9
+ def process message, routing
10
+
11
+ unless ( routing[:destination].name == @queue ) then
12
+ ActiveMessaging.logger.debug "Trace: direction = #{routing[:direction]} publisher=#{routing[:publisher]} queue=#{routing[:destination].name} @queue=#{@queue}"
13
+ if routing[:direction].to_sym==:outgoing then
14
+ "trace from outgoing"
15
+ publish @queue, "<sent>"+
16
+ "<from>#{routing[:publisher]}</from>" +
17
+ "<queue>#{routing[:destination].name}</queue>" +
18
+ "<message>#{message.body}</message>" +
19
+ "</sent>"
20
+ end
21
+ if routing[:direction].to_sym==:incoming then
22
+ "trace from incoming"
23
+ publish @queue, "<received>"+
24
+ "<by>#{routing[:receiver]}</by>" +
25
+ "<queue>#{routing[:destination].name}</queue>" +
26
+ "<message>#{message.body}</message>" +
27
+ "</received>"
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,21 @@
1
+ Description:
2
+ Configures your application to use active messaging. The following files are installed:
3
+ 1. config/broker.yml - Configures the broker that you will be using.
4
+ 2. script/poller - This script will start/stop/run the process that will be polling your broker. The name of this file/process is configurable. See Usage below.
5
+ 3. lib/poller.rb - The poller script will use this file to start up ActiveMesssaging
6
+
7
+ The generator will also create a app/processors directory and modify your application.rb so that app/processors is in the autoload path
8
+
9
+ Usage:
10
+ If you do not pass in an argument then the poller filename/process will be called poller. You can override this default by passing in the name that you want the file and process to be.
11
+
12
+ Examples:
13
+ rails g activemessaging:install
14
+
15
+ Installs activemessaging with the poller process named poller
16
+
17
+ rails g activemessaging:install POLLER_NAME
18
+
19
+ Installs activemessaging but allows you to customize the name of the poller
20
+
21
+
@@ -0,0 +1,39 @@
1
+ module ActiveMessaging
2
+ class InstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ argument :poller_name, :type => :string, :default => 'poller', :banner => 'poller_name'
6
+
7
+ def copy_application
8
+ copy_file "application_processor.rb", "app/processors/application_processor.rb"
9
+ end
10
+
11
+ def copy_poller
12
+ template "poller", "script/#{poller_name}"
13
+ chmod("script/#{poller_name}", 0755)
14
+ end
15
+
16
+ def copy_threaded_poller
17
+ template "threaded_poller", "script/threaded_#{poller_name}"
18
+ chmod("script/threaded_#{poller_name}", 0755)
19
+ end
20
+
21
+ def copy_poller_rb
22
+ copy_file "poller.rb", "lib/#{poller_name}.rb"
23
+ end
24
+
25
+ def copy_broker_rb
26
+ copy_file "broker.yml", "config/broker.yml"
27
+ end
28
+
29
+ def add_gems
30
+ gem("daemons")
31
+ end
32
+
33
+
34
+ def change_application
35
+ application ' config.autoload_paths += %W(#{config.root}/app/processors)'
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ class ApplicationProcessor < ActiveMessaging::Processor
2
+
3
+ # Default on_error implementation - logs standard errors but keeps processing. Other exceptions are raised.
4
+ # Have on_error throw ActiveMessaging::AbortMessageException when you want a message to be aborted/rolled back,
5
+ # meaning that it can and should be retried (idempotency matters here).
6
+ # Retry logic varies by broker - see individual adapter code and docs for how it will be treated
7
+ def on_error(err)
8
+ if (err.kind_of?(StandardError))
9
+ logger.error "ApplicationProcessor::on_error: #{err.class.name} rescued:\n" + \
10
+ err.message + "\n" + \
11
+ "\t" + err.backtrace.join("\n\t")
12
+ else
13
+ logger.error "ApplicationProcessor::on_error: #{err.class.name} raised: " + err.message
14
+ raise err
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,139 @@
1
+ #
2
+ # broker.yml
3
+ #
4
+ # Simple yaml file for the env specific configuration of the broker connections.
5
+ # See the wiki for more information: http://code.google.com/p/activemessaging/wiki/Configuration
6
+ #
7
+ development:
8
+ ############################
9
+ # Stomp Adapter Properties #
10
+ ############################
11
+ adapter: stomp
12
+
13
+ # properties below are all defaults for this adapter
14
+ # login: ""
15
+ # passcode: ""
16
+ # host: localhost
17
+ # port: 61613
18
+ # reliable: true
19
+ # reconnectDelay: 5
20
+
21
+ # NEW! enable stomp retry logic
22
+ # will resend errored out messages to be retried when on_error throws ActiveMessaging::AbortMessageException
23
+ #
24
+ # Max number of times to retry an aborted message, for 0, will not retry (default)
25
+ # retryMax: 0
26
+ #
27
+ # If error still occurs after retryMax, send message to specified dead letter queue
28
+ # deadLetterQueue: '/queue/activemessaging/deadletter'
29
+
30
+
31
+ ###########################
32
+ # AMQP Adapter Properties #
33
+ ###########################
34
+ # adapter: amqp
35
+
36
+ # properties below are defaults for this adapter
37
+ # host: localhost
38
+ # port: 5672
39
+ # user: guest
40
+ # pass: guest
41
+ # vhost: /
42
+ # ssl: false
43
+ # ssl_verify: 1
44
+ # debug: 0
45
+ # queue_name: <autogenerated>
46
+ # queue_durable: false if queue_name is autogenerated, defaults to true otherwise
47
+ # queue_auto_delete: true if queue_name is autogenerated, defaults to false otherwise
48
+ # queue_exclusive: true if queue_name is autogenerated, defaults to true otherwise
49
+
50
+ # SSL:
51
+
52
+ # in order to use SSL you will need to use the following fork of the carrot project:
53
+ #
54
+ # http://github.com/rabbitt/carrot
55
+ #
56
+ # If your certificate is self signed, you will want to set ssl_verify to 0 which corresponds to
57
+ # OpenSSL::SSL::VERIFY_NONE. Otherwise, it defaults to 1 (OpenSSL::SSL::VERIFY_PEER).
58
+
59
+ # QUEUE_*:
60
+
61
+ # queue_name is the name of the "inbox" queue that will be bound to all subscription keys (called queues
62
+ # or destinations here). In other words, you only have one queue where all messages end up using this
63
+ # adapter, and it is bound to the relevant exchanges using routing keys and exchange information
64
+ # you provide in your messages.rb and subscribes_to calls. For example,
65
+ #
66
+ # in messages.rb:
67
+ # s.queue :hello_world, 'hello.world', :exchange_type => :direct, :exchange_name => 'amq.direct'
68
+ #
69
+ # in a processor:
70
+ # subscribes_to :hello_world, :routing_key => 'hello.#'
71
+ #
72
+ # in a model:
73
+ # publish :hello_world, 'Hello world!', :routing_key => 'hello.world'
74
+
75
+
76
+ # Note: in the event that you don't specify a routing_key on publish, the queue_name of the specified
77
+ # destination (as listed in messages.rb) will be used as the routing_key when publishing.
78
+
79
+ ################################
80
+ # Beanstalk Adapter Properties #
81
+ ################################
82
+ # adapter: beanstalk
83
+ # host: localhost
84
+
85
+ ## properties below are all defaults for this adapter
86
+ # port: 11300
87
+
88
+
89
+ #################################
90
+ # Amazon SQS Adapter Properties #
91
+ #################################
92
+ # adapter: asqs
93
+ # access_key_id: XXXXXXXXXXXXXXXXXXXX
94
+ # secret_access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
95
+
96
+ ## properties below are all defaults for this adapter
97
+ # host: queue.amazonaws.com
98
+ # port: 80
99
+ # reliable: true
100
+ # reconnectDelay: 5
101
+ # aws_version: 2006-04-01
102
+ # content_type: text/plain
103
+ # poll_interval: 1
104
+ # cache_queue_list: true
105
+
106
+
107
+ ########################################
108
+ # ReliableMessaging Adapter Properties #
109
+ ########################################
110
+ # adapter: reliable_msg
111
+
112
+ ## properties below are all defaults for this adapter
113
+ # poll_interval: 1
114
+ # reliable: true
115
+
116
+
117
+ ###################################
118
+ # Websphere MQ Adapter Properties #
119
+ ###################################
120
+ # adapter: wmq
121
+ # q_mgr_name: ""
122
+ # poll_interval: .1
123
+
124
+
125
+
126
+ test:
127
+ adapter: test
128
+ reliable: false
129
+
130
+ production:
131
+ adapter: stomp
132
+ reliable: true
133
+ # properties below are all defaults for this adapter
134
+ # login: ""
135
+ # passcode: ""
136
+ # host: localhost
137
+ # port: 61613
138
+ # reliable: true
139
+ # reconnectDelay: 5
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV['APP_ROOT'] ||= File.expand_path(File.join(File.dirname(__FILE__), '..'))
4
+ APP_ROOT = ENV['APP_ROOT']
5
+ script_file = File.join(APP_ROOT, 'lib', '<%=poller_name%>.rb')
6
+ tmp_dir = File.join(APP_ROOT, 'tmp')
7
+
8
+ require 'rubygems'
9
+ require 'daemons'
10
+
11
+
12
+ options = {
13
+ :app_name => "<%=poller_name%>",
14
+ :dir_mode => :normal,
15
+ :dir => tmp_dir,
16
+ :multiple => true,
17
+ :ontop => false,
18
+ :mode => :load,
19
+ :backtrace => true,
20
+ :monitor => true,
21
+ :log_output => true
22
+ }
23
+
24
+ Daemons.run(script_file,options)
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # Make sure stdout and stderr write out without delay for using with daemon like scripts
3
+ STDOUT.sync = true; STDOUT.flush
4
+ STDERR.sync = true; STDERR.flush
5
+
6
+ app_root = ENV['APP_ROOT'] || File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
7
+ application_file = File.join(app_root, 'config', 'environment.rb')
8
+
9
+ if File.exist?(application_file)
10
+ load application_file
11
+ else
12
+ raise "#{application_file} does not exist!"
13
+ end
14
+
15
+ Rails.logger = Logger.new(STDOUT)
16
+ ActiveMessaging.logger = Rails.logger
17
+
18
+ # Load ActiveMessaging
19
+ ActiveMessaging::load_processors
20
+
21
+ # Start it up!
22
+ ActiveMessaging::start
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # The threaded poller will use celluloid to generate many threads for a single poller process to handle messages
4
+ # Yes, I absolutely looked at the sidekiq manager code, and this code is very very similar
5
+ # This script also shows how to use the poller without loading Rails, though it loads the app lib directory
6
+ # this is tested on 1.9.3, and rails 3+
7
+
8
+ # Make sure stdout and stderr write out without delay for using with daemon like scripts
9
+ STDOUT.sync = true; STDOUT.flush
10
+ STDERR.sync = true; STDERR.flush
11
+
12
+ # we're not going to load rails, but activemessaging does expect there to be an app root
13
+ # this goes back to when it was used in both rails or merb, but work with just not loading a framework
14
+ app_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
15
+ ENV['APP_ROOT'] ||= app_root
16
+
17
+ # minimal requirements, other requires are in the lib
18
+ require 'rubygems'
19
+ require 'bundler/setup'
20
+
21
+ # load the app lib directory
22
+ lib_path = File.dirname("#{app_root}/lib")
23
+ $:.unshift(lib_path)
24
+ Dir["#{lib_path}/**/*.rb"].each {|file| require file unless file.match(/poller\.rb/) }
25
+
26
+ # require and load activemessaging
27
+ require 'activemessaging'
28
+ ActiveMessaging.load_activemessaging
29
+ require 'activemessaging/threaded_poller'
30
+
31
+ # configure the connection (there can be multiple defined in broker.yml) and number of threads
32
+ connection_name = 'default'
33
+ configuration = [{:pool_size => 3}]
34
+
35
+ # start it up!
36
+ begin
37
+ trap("TERM", "EXIT")
38
+ @poller = ActiveMessaging::ThreadedPoller.new(connection_name, configuration)
39
+ @poller.start!
40
+ sleep
41
+ rescue Interrupt
42
+ puts "-- Interrupt --"
43
+ @poller.stop!
44
+ @poller.wait(:shutdown)
45
+ exit(0)
46
+ end
@@ -0,0 +1,2 @@
1
+ Generates a stub ActiveMessaging Processor and associated test.
2
+
@@ -0,0 +1,39 @@
1
+ module ActiveMessaging
2
+ class ProcessorGenerator < Rails::Generators::NamedBase
3
+ # namespace "activemessaging"
4
+ source_root File.expand_path("../templates", __FILE__)
5
+
6
+ # check_class_collision :suffix=>"Processor"
7
+
8
+ def copy_processor
9
+ template "processor.rb", "app/processors/#{file_name}_processor.rb"
10
+ end
11
+
12
+ def copy_messaging
13
+ template "messaging.rb", "config/messaging.rb"
14
+ end
15
+
16
+ hook_for :test_framework, :as => :active_messaging_processor
17
+
18
+ end
19
+ end
20
+
21
+ module TestUnit
22
+ class ActiveMessagingProcessor < Rails::Generators::NamedBase
23
+ source_root File.expand_path("../templates", __FILE__)
24
+
25
+ def copy_processor
26
+ template "processor_test.rb", "test/functional/#{file_name}_processor_test.rb"
27
+ end
28
+ end
29
+ end
30
+
31
+ module Rspec
32
+ class ActiveMessagingProcessor < Rails::Generators::NamedBase
33
+ source_root File.expand_path("../templates", __FILE__)
34
+
35
+ def copy_processor
36
+ template "processor_spec.rb", "spec/functional/#{file_name}_processor_spec.rb"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ #
2
+ # Add your destination definitions here
3
+ # can also be used to configure filters, and processor groups
4
+ #
5
+ ActiveMessaging::Gateway.define do |s|
6
+ #s.destination :orders, '/queue/Orders'
7
+ #s.filter :some_filter, :only=>:orders
8
+ #s.processor_group :group1, :order_processor
9
+
10
+ s.destination :<%= singular_name %>, '/queue/<%= class_name %>'
11
+
12
+ end
@@ -0,0 +1,8 @@
1
+ class <%= class_name %>Processor < ApplicationProcessor
2
+
3
+ subscribes_to :<%= singular_name %>
4
+
5
+ def on_message(message)
6
+ logger.debug "<%= class_name %>Processor received: " + message
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'activemessaging/test_helper'
3
+ require File.dirname(__FILE__) + '/../../app/processors/application_processor'
4
+
5
+ describe <%= class_name %>Processor do
6
+
7
+ include ActiveMessaging::TestHelper
8
+
9
+ before(:each) do
10
+ load File.dirname(__FILE__) + "/../../app/processors/<%= file_name %>_processor.rb"
11
+ @processor = <%= class_name %>Processor.new
12
+ end
13
+
14
+ after(:each) do
15
+ @processor = nil
16
+ end
17
+
18
+ it "should receive message" do
19
+ @processor.on_message('Your test message here!')
20
+ end
21
+
22
+
23
+
24
+ end