activemessaging 0.7.1 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -19,4 +19,10 @@ h1. Support
19
19
 
20
20
  Best bet is the google groups mailing list:
21
21
 
22
- http://groups.google.com/group/activemessaging-discuss
22
+ http://groups.google.com/group/activemessaging-discuss
23
+
24
+ h1. Fork Details
25
+
26
+ This fork adds the ability to specify a dead letter queue prefix so instead of all messages going to 1 dead letter queue, each message will go to a dead letter queue that is based on the deadLetterQueuePrefix configuration property and the originating queue.
27
+
28
+ For example, if you specific a deadLetterQueuePrefix of "DLQ." in your broker.yml and the originating queue is /queue/myqueue then the dead letter queue will be /queue/DLQ.myqueue
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ begin
26
26
  # basic
27
27
  gemspec.name = "activemessaging"
28
28
  gemspec.summary = "Official activemessaging gem, now hosted on github.com/kookster. (kookster prefix temporary)"
29
- gemspec.description = "ActiveMessaging is an attempt to bring the simplicity and elegance of rails development to the world of messaging. Messaging, (or event-driven architecture) is widely used for enterprise integration, with frameworks such as Java's JMS, and products such as ActiveMQ, Tibco, IBM MQSeries, etc."
29
+ gemspec.description = "ActiveMessaging is an attempt to bring the simplicity and elegance of rails development to the world of messaging. Messaging, (or event-driven architecture) is widely used for enterprise integration, with frameworks such as Java's JMS, and products such as ActiveMQ, Tibco, IBM MQSeries, etc. Now supporting Rails 3 as of version 0.8.0."
30
30
  gemspec.email = "activemessaging-discuss@googlegroups.com"
31
31
  gemspec.homepage = "http://github.com/kookster/activemessaging"
32
32
  gemspec.authors = ["Jon Tirsen", "Andrew Kuklewicz", "Olle Jonsson", "Sylvain Perez", "Cliff Moon", 'Uwe Kubosch']
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.1
1
+ 0.8.1
@@ -1,107 +1,107 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{activemessaging}
8
- s.version = "0.7.1"
8
+ s.version = "0.8.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jon Tirsen", "Andrew Kuklewicz", "Olle Jonsson", "Sylvain Perez", "Cliff Moon", "Uwe Kubosch"]
12
- s.date = %q{2010-04-08}
13
- s.description = %q{ActiveMessaging is an attempt to bring the simplicity and elegance of rails development to the world of messaging. Messaging, (or event-driven architecture) is widely used for enterprise integration, with frameworks such as Java's JMS, and products such as ActiveMQ, Tibco, IBM MQSeries, etc.}
12
+ s.date = %q{2011-08-15}
13
+ s.description = %q{ActiveMessaging is an attempt to bring the simplicity and elegance of rails development to the world of messaging. Messaging, (or event-driven architecture) is widely used for enterprise integration, with frameworks such as Java's JMS, and products such as ActiveMQ, Tibco, IBM MQSeries, etc. Now supporting Rails 3 as of version 0.8.0.}
14
14
  s.email = %q{activemessaging-discuss@googlegroups.com}
15
15
  s.extra_rdoc_files = [
16
16
  "README"
17
17
  ]
18
18
  s.files = [
19
19
  "README",
20
- "Rakefile",
21
- "VERSION",
22
- "activemessaging.gemspec",
23
- "generators/a13g_test_harness/a13g_test_harness_generator.rb",
24
- "generators/a13g_test_harness/templates/active_messaging_test.rhtml",
25
- "generators/a13g_test_harness/templates/active_messaging_test_controller.rb",
26
- "generators/a13g_test_harness/templates/index.rhtml",
27
- "generators/filter/USAGE",
28
- "generators/filter/filter_generator.rb",
29
- "generators/filter/templates/filter.rb",
30
- "generators/filter/templates/filter_test.rb",
31
- "generators/processor/USAGE",
32
- "generators/processor/processor_generator.rb",
33
- "generators/processor/templates/application.rb",
34
- "generators/processor/templates/broker.yml",
35
- "generators/processor/templates/jruby_poller",
36
- "generators/processor/templates/messaging.rb",
37
- "generators/processor/templates/poller",
38
- "generators/processor/templates/poller.rb",
39
- "generators/processor/templates/processor.rb",
40
- "generators/processor/templates/processor_test.rb",
41
- "generators/tracer/USAGE",
42
- "generators/tracer/templates/controller.rb",
43
- "generators/tracer/templates/helper.rb",
44
- "generators/tracer/templates/index.rhtml",
45
- "generators/tracer/templates/layout.rhtml",
46
- "generators/tracer/templates/trace_processor.rb",
47
- "generators/tracer/tracer_generator.rb",
48
- "init.rb",
49
- "lib/activemessaging.rb",
50
- "lib/activemessaging/adapter.rb",
51
- "lib/activemessaging/adapters/asqs.rb",
52
- "lib/activemessaging/adapters/base.rb",
53
- "lib/activemessaging/adapters/beanstalk.rb",
54
- "lib/activemessaging/adapters/jms.rb",
55
- "lib/activemessaging/adapters/reliable_msg.rb",
56
- "lib/activemessaging/adapters/stomp.rb",
57
- "lib/activemessaging/adapters/test.rb",
58
- "lib/activemessaging/adapters/wmq.rb",
59
- "lib/activemessaging/base_message.rb",
60
- "lib/activemessaging/filter.rb",
61
- "lib/activemessaging/gateway.rb",
62
- "lib/activemessaging/message_sender.rb",
63
- "lib/activemessaging/named_base.rb",
64
- "lib/activemessaging/processor.rb",
65
- "lib/activemessaging/support.rb",
66
- "lib/activemessaging/test_helper.rb",
67
- "lib/activemessaging/trace_filter.rb",
68
- "poller.rb",
69
- "tasks/start_consumers.rake",
70
- "test/all_tests.rb",
71
- "test/app/config/broker.yml",
72
- "test/asqs_test.rb",
73
- "test/config_test.rb",
74
- "test/filter_test.rb",
75
- "test/gateway_test.rb",
76
- "test/jms_test.rb",
77
- "test/reliable_msg_test.rb",
78
- "test/stomp_test.rb",
79
- "test/test_helper.rb",
80
- "test/tracer_test.rb"
20
+ "Rakefile",
21
+ "VERSION",
22
+ "activemessaging.gemspec",
23
+ "generators/a13g_test_harness/a13g_test_harness_generator.rb",
24
+ "generators/a13g_test_harness/templates/active_messaging_test.rhtml",
25
+ "generators/a13g_test_harness/templates/active_messaging_test_controller.rb",
26
+ "generators/a13g_test_harness/templates/index.rhtml",
27
+ "generators/filter/USAGE",
28
+ "generators/filter/filter_generator.rb",
29
+ "generators/filter/templates/filter.rb",
30
+ "generators/filter/templates/filter_test.rb",
31
+ "generators/processor/USAGE",
32
+ "generators/processor/processor_generator.rb",
33
+ "generators/processor/templates/application.rb",
34
+ "generators/processor/templates/broker.yml",
35
+ "generators/processor/templates/jruby_poller",
36
+ "generators/processor/templates/messaging.rb",
37
+ "generators/processor/templates/poller",
38
+ "generators/processor/templates/poller.rb",
39
+ "generators/processor/templates/processor.rb",
40
+ "generators/processor/templates/processor_test.rb",
41
+ "generators/tracer/USAGE",
42
+ "generators/tracer/templates/controller.rb",
43
+ "generators/tracer/templates/helper.rb",
44
+ "generators/tracer/templates/index.rhtml",
45
+ "generators/tracer/templates/layout.rhtml",
46
+ "generators/tracer/templates/trace_processor.rb",
47
+ "generators/tracer/tracer_generator.rb",
48
+ "init.rb",
49
+ "lib/activemessaging.rb",
50
+ "lib/activemessaging/adapter.rb",
51
+ "lib/activemessaging/adapters/amqp.rb",
52
+ "lib/activemessaging/adapters/asqs.rb",
53
+ "lib/activemessaging/adapters/base.rb",
54
+ "lib/activemessaging/adapters/beanstalk.rb",
55
+ "lib/activemessaging/adapters/jms.rb",
56
+ "lib/activemessaging/adapters/reliable_msg.rb",
57
+ "lib/activemessaging/adapters/stomp.rb",
58
+ "lib/activemessaging/adapters/synch.rb",
59
+ "lib/activemessaging/adapters/test.rb",
60
+ "lib/activemessaging/adapters/wmq.rb",
61
+ "lib/activemessaging/base_message.rb",
62
+ "lib/activemessaging/filter.rb",
63
+ "lib/activemessaging/gateway.rb",
64
+ "lib/activemessaging/message_sender.rb",
65
+ "lib/activemessaging/named_base.rb",
66
+ "lib/activemessaging/processor.rb",
67
+ "lib/activemessaging/railtie.rb",
68
+ "lib/activemessaging/test_helper.rb",
69
+ "lib/activemessaging/trace_filter.rb",
70
+ "lib/tasks/start_consumers.rake",
71
+ "poller.rb",
72
+ "test/all_tests.rb",
73
+ "test/app/config/broker.yml",
74
+ "test/asqs_test.rb",
75
+ "test/config_test.rb",
76
+ "test/filter_test.rb",
77
+ "test/gateway_test.rb",
78
+ "test/jms_test.rb",
79
+ "test/reliable_msg_test.rb",
80
+ "test/stomp_test.rb",
81
+ "test/test_helper.rb",
82
+ "test/tracer_test.rb"
81
83
  ]
82
84
  s.homepage = %q{http://github.com/kookster/activemessaging}
83
- s.rdoc_options = ["--charset=UTF-8"]
84
85
  s.require_paths = ["lib"]
85
- s.rubygems_version = %q{1.3.5}
86
+ s.rubygems_version = %q{1.4.2}
86
87
  s.summary = %q{Official activemessaging gem, now hosted on github.com/kookster. (kookster prefix temporary)}
87
88
  s.test_files = [
88
89
  "test/all_tests.rb",
89
- "test/asqs_test.rb",
90
- "test/config_test.rb",
91
- "test/filter_test.rb",
92
- "test/gateway_test.rb",
93
- "test/jms_test.rb",
94
- "test/reliable_msg_test.rb",
95
- "test/stomp_test.rb",
96
- "test/test_helper.rb",
97
- "test/tracer_test.rb"
90
+ "test/asqs_test.rb",
91
+ "test/config_test.rb",
92
+ "test/filter_test.rb",
93
+ "test/gateway_test.rb",
94
+ "test/jms_test.rb",
95
+ "test/reliable_msg_test.rb",
96
+ "test/stomp_test.rb",
97
+ "test/test_helper.rb",
98
+ "test/tracer_test.rb"
98
99
  ]
99
100
 
100
101
  if s.respond_to? :specification_version then
101
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
102
102
  s.specification_version = 3
103
103
 
104
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
104
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
105
105
  s.add_runtime_dependency(%q<activesupport>, [">= 1.0.0"])
106
106
  else
107
107
  s.add_dependency(%q<activesupport>, [">= 1.0.0"])
@@ -27,6 +27,55 @@ development:
27
27
  # If error still occurs after retryMax, send message to specified dead letter queue
28
28
  # deadLetterQueue: '/queue/activemessaging/deadletter'
29
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
+
30
79
  ################################
31
80
  # Beanstalk Adapter Properties #
32
81
  ################################
data/init.rb CHANGED
@@ -1,3 +1 @@
1
- require 'active_support'
2
- require 'ostruct'
3
1
  require 'activemessaging'
@@ -1,7 +1,13 @@
1
+ require 'active_support'
2
+ require 'ostruct'
3
+
4
+ if defined?(Rails::Railtie)
5
+ require 'activemessaging/railtie.rb'
6
+ end
7
+
1
8
  module ActiveMessaging
2
- APP_ROOT = ENV['APP_ROOT'] || ENV['RAILS_ROOT'] || ((defined? RAILS_ROOT) && RAILS_ROOT) || File.dirname($0)
3
- APP_ENV = ENV['APP_ENV'] || ENV['RAILS_ENV'] || 'development'
4
- ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
9
+
10
+ ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
5
11
 
6
12
  # Used to indicate that the processing for a thread shoud complete
7
13
  class StopProcessingException < Interrupt #:nodoc:
@@ -17,18 +23,27 @@ module ActiveMessaging
17
23
  class StopFilterException < Exception #:nodoc:
18
24
  end
19
25
 
20
- def ActiveMessaging.logger
26
+ def self.logger
21
27
  @@logger = nil unless defined? @@logger
22
- @@logger ||= RAILS_DEFAULT_LOGGER if defined? RAILS_DEFAULT_LOGGER
23
- @@logger ||= ActiveRecord::Base.logger if defined? ActiveRecord
28
+ @@logger ||= Rails.logger if defined? Rails
24
29
  @@logger ||= Logger.new(STDOUT)
25
30
  @@logger
26
31
  end
27
32
 
28
- # DEPRECATED, so I understand, but I'm using it nicely below.
33
+ def self.logger=(logger)
34
+ @@logger = logger
35
+ end
36
+
37
+ def self.app_root
38
+ @@app_root ||= (ENV['APP_ROOT'] || (defined?(::Rails) && ::Rails.root) || ENV['RAILS_ROOT'] || File.dirname($0))
39
+ end
40
+
41
+ def self.app_env
42
+ @@app_env ||= (ENV['APP_ENV'] || (defined?(::Rails) && ::Rails.env) || ENV['RAILS_ENV'] || 'development')
43
+ end
44
+
29
45
  def self.load_extensions
30
46
  require 'logger'
31
- require 'activemessaging/support'
32
47
  require 'activemessaging/gateway'
33
48
  require 'activemessaging/adapter'
34
49
  require 'activemessaging/message_sender'
@@ -42,32 +57,28 @@ module ActiveMessaging
42
57
  adapter_name = File.basename(a, ".rb")
43
58
  require 'activemessaging/adapters/' + adapter_name
44
59
  rescue RuntimeError, LoadError => e
45
- logger.debug "ActiveMessaging: adapter #{adapter_name} not loaded: #{ e.message }"
60
+ logger.warn "ActiveMessaging: adapter #{adapter_name} not loaded: #{ e.message }"
46
61
  end
47
62
  end
48
63
  end
49
64
 
50
65
  def self.load_config
51
- path = File.expand_path("#{APP_ROOT}/config/messaging.rb")
66
+ path = File.expand_path("#{app_root}/config/messaging.rb")
52
67
  begin
53
68
  load path
54
69
  rescue MissingSourceFile
55
- logger.debug "ActiveMessaging: no '#{path}' file to load"
70
+ logger.error "ActiveMessaging: no '#{path}' file to load"
56
71
  rescue
57
72
  raise $!, " ActiveMessaging: problems trying to load '#{path}': \n\t#{$!.message}"
58
73
  end
59
74
  end
60
75
 
61
76
  def self.load_processors(first=true)
62
- #Load the parent processor.rb, then all child processor classes
63
- load APP_ROOT + '/vendor/plugins/activemessaging/lib/activemessaging/message_sender.rb' unless defined?(ActiveMessaging::MessageSender)
64
- load APP_ROOT + '/vendor/plugins/activemessaging/lib/activemessaging/processor.rb' unless defined?(ActiveMessaging::Processor)
65
- load APP_ROOT + '/vendor/plugins/activemessaging/lib/activemessaging/filter.rb' unless defined?(ActiveMessaging::Filter)
66
- logger.debug "ActiveMessaging: Loading #{APP_ROOT + '/app/processors/application.rb'}" if first
67
- load APP_ROOT + '/app/processors/application.rb' if File.exist?("#{APP_ROOT}/app/processors/application.rb")
68
- Dir[APP_ROOT + '/app/processors/*.rb'].each do |f|
77
+ logger.info "ActiveMessaging: Loading #{app_root}/app/processors/application.rb" if first
78
+ load "#{app_root}/app/processors/application.rb" if File.exist?("#{app_root}/app/processors/application.rb")
79
+ Dir["#{app_root}/app/processors/*.rb"].each do |f|
69
80
  unless f.match(/\/application.rb/)
70
- logger.debug "ActiveMessaging: Loading #{f}" if first
81
+ logger.info "ActiveMessaging: Loading #{f}" if first
71
82
  load f
72
83
  end
73
84
  end
@@ -92,17 +103,20 @@ module ActiveMessaging
92
103
 
93
104
  def self.start
94
105
  if ActiveMessaging::Gateway.subscriptions.empty?
95
- err_msg = <<EOM
106
+ err_msg = <<-EOM
96
107
 
97
- ActiveMessaging Error: No subscriptions.
98
- If you have no processor classes in app/processors, add them using the command:
99
- script/generate processor DoSomething"
108
+ ActiveMessaging Error: No subscriptions.
109
+
110
+ If you have no processor classes in app/processors, add them using the command:
111
+ script/generate processor DoSomething"
100
112
 
101
- If you have processor classes, make sure they include in the class a call to 'subscribes_to':
102
- class DoSomethingProcessor < ActiveMessaging::Processor
103
- subscribes_to :do_something
113
+ If you have processor classes, make sure they include in the class a call to 'subscribes_to':
114
+ class DoSomethingProcessor < ActiveMessaging::Processor
115
+ subscribes_to :do_something
116
+ # ...
117
+ end
104
118
 
105
- EOM
119
+ EOM
106
120
  puts err_msg
107
121
  logger.error err_msg
108
122
  exit
@@ -112,19 +126,3 @@ EOM
112
126
  end
113
127
 
114
128
  end
115
-
116
- #load these once to start with
117
- ActiveMessaging.load_activemessaging
118
-
119
- # reload these on each Rails request - leveraging Dispatcher semantics for consistency
120
- if defined? Rails
121
- ActiveMessaging.logger.info "Rails available: Adding dispatcher prepare callback."
122
- require 'dispatcher' unless defined?(::Dispatcher)
123
-
124
- # add processors and config to on_prepare if supported (rails 1.2+)
125
- if ::Dispatcher.respond_to? :to_prepare
126
- ::Dispatcher.to_prepare :activemessaging do
127
- ActiveMessaging.reload_activemessaging
128
- end
129
- end
130
- end
@@ -12,8 +12,7 @@ module ActiveMessaging
12
12
  end
13
13
 
14
14
  def logger()
15
- @@logger = ActiveMessaging.logger unless defined?(@@logger)
16
- @@logger
15
+ @@logger ||= ActiveMessaging.logger
17
16
  end
18
17
 
19
18
  end
@@ -0,0 +1,215 @@
1
+ require 'carrot'
2
+ require 'digest/md5'
3
+ require 'bert'
4
+
5
+ # make sure ActiveMessaging::Processor is already loaded so we actually override it!
6
+ require 'activemessaging/processor'
7
+ require 'activemessaging/adapters/base'
8
+
9
+ require 'emissary/message'
10
+
11
+ module ActiveMessaging
12
+ class Processor
13
+ def self.subscribes_to destination_name, headers={}
14
+ # let's default to using the same exchange_type/exchange_name as defined in the messages.rb
15
+ # for the given destination. XXX: THIS IS A BIG TIME MONKEY PATCH! Might consider pushing a
16
+ # proper patch upstream instead of jury-rigging this.
17
+ d = ActiveMessaging::Gateway.find_destination(destination_name)
18
+ type, name = [ d.publish_headers[:exchange_type], d.publish_headers[:exchange_name] ]
19
+ ActiveMessaging::Gateway.subscribe_to destination_name, self, { :exchange_type => type, :exchange_name => name }.merge(headers)
20
+ end
21
+ end
22
+
23
+ module Adapters
24
+ module Amqp
25
+ class Connection
26
+ include ActiveMessaging::Adapter
27
+ register :amqp
28
+
29
+ SERVER_RETRY_MAX_ATTEMPTS = 10
30
+
31
+ DEFAULT_QUEUE_CONFIG = {
32
+ :durable => true,
33
+ :auto_delete => false,
34
+ :exclusive => true
35
+ }
36
+
37
+ class InvalidExchangeType < ArgumentError; end
38
+
39
+ def initialize config = {}
40
+ @connect_options = {
41
+ :user => config[:user] || 'guest',
42
+ :pass => config[:pass] || 'guest',
43
+ :host => config[:host] || 'localhost',
44
+ :port => config[:port] || (config[:ssl] ? 5671 : 5672),
45
+ :vhost => config[:vhost] || nil,
46
+ :ssl => config[:ssl] || false,
47
+ :ssl_verify => config[:ssl_verify] || OpenSSL::SSL::VERIFY_PEER,
48
+ }
49
+
50
+ @debug = config[:debug].to_i rescue 0
51
+
52
+ Carrot.logging = true unless @debug < 5
53
+
54
+ @auto_generated_queue = false
55
+ unless config[:queue_name]
56
+ @queue_name = Digest::MD5.hexdigest Time.now.to_s
57
+ @auto_generated_queue = true
58
+ else
59
+ @queue_name = config[:queue_name]
60
+ end
61
+
62
+ @queue_config = DEFAULT_QUEUE_CONFIG
63
+ unless @auto_generated_queue
64
+ @queue_config.merge({
65
+ :durable => !!config[:queue_durable],
66
+ :auto_delete => !!config[:queue_auto_delete],
67
+ :exclusive => !!config[:queue_exclusive]
68
+ })
69
+ end
70
+ end
71
+
72
+ def received message, headers = {}
73
+ puts "Received Message - ACK'ing with delivery_tag '#{message.headers[:delivery_tag]}'" if @debug > 0
74
+ client.server.send_frame(::Carrot::AMQP::Protocol::Basic::Ack.new(:delivery_tag => message.headers[:delivery_tag]))
75
+ end
76
+
77
+ def unreceive message, headers = {}
78
+ puts "Un-Receiving Message - REJECTing with delivery_tag '#{message.headers[:delivery_tag]}'" if @debug > 0
79
+ client.server.send_frame(::Carrot::AMQP::Protocol::Basic::Reject.new(:delivery_tag => message.headers[:delivery_tag]))
80
+ end
81
+
82
+ def receive
83
+ while true
84
+ message = queue.pop(:ack => true)
85
+ unless message.nil?
86
+ message = AmqpMessage.decode(message).stamp_received! unless message.nil?
87
+ message.delivery_tag = queue.delivery_tag
88
+ puts "RECEIVE: #{message.inspect}" if @debug
89
+ return message
90
+ end
91
+ sleep 0.2
92
+ end
93
+ end
94
+
95
+ def send queue_name, data, headers = {}
96
+ headers[:routing_key] ||= queue_name
97
+ message = AmqpMessage.new({:headers => headers, :data => data}, queue_name)
98
+
99
+ if @debug > 0
100
+ puts "Sending the following message: "; pp message
101
+ end
102
+
103
+ begin
104
+ exchange(*exchange_info(headers)).publish(message.stamp_sent!.encode, :key => headers[:routing_key])
105
+ rescue ::Carrot::AMQP::Server::ServerDown
106
+ retry_attempts = retry_attempts.nil? ? 1 : retry_attempts + 1
107
+ sleep(retry_attempts * 0.25)
108
+ retry unless retry_attempts >= SERVER_RETRY_MAX_ATTEMPTS
109
+ raise e
110
+ end
111
+ end
112
+
113
+ def subscribe queue_name, headers = {}, subId = nil
114
+ if @debug > 1
115
+ puts "Begin Subscribe Request:"
116
+ puts " Queue Name: #{queue_name.inspect}"
117
+ puts " Headers: #{headers.inspect}"
118
+ puts " subId: #{subId.inspect}"
119
+ puts " EXCH INFO: #{exchange_info(headers).inspect}"
120
+ puts "End Subscribe Request."
121
+ end
122
+
123
+ routing_key = headers[:routing_key] || queue_name
124
+ queue.bind(exchange(*exchange_info(headers)), :key => routing_key)
125
+ end
126
+
127
+ def unsubscribe(queue_name, headers={}, subId=nil)
128
+ if @debug > 1
129
+ puts "Begin UNsubscribe Request:"
130
+ puts " Queue Name: #{queue_name.inspect}"
131
+ puts " Headers: #{headers.inspect}"
132
+ puts " subId: #{subId.inspect}"
133
+ puts "End UNsubscribe Request."
134
+ end
135
+
136
+ routing_key = headers[:routing_key] || queue_name
137
+ queue.unbind(exchange(*exchange_info(headers)), :key => routing_key)
138
+ end
139
+
140
+ def disconnect(headers={})
141
+ @client.stop
142
+ end
143
+
144
+ private
145
+
146
+ def exchange_info headers
147
+ [ (headers[:exchange_type].to_sym rescue nil) || :direct, headers[:exchange_name] || nil]
148
+ end
149
+
150
+ def exchange type, name, *args
151
+ type = type.to_sym rescue nil
152
+ unless [:topic, :fanout, :direct].include? type
153
+ raise InvalidExchangeType, "The carrot library does not support an exchange type of '#{type.inspect}'"
154
+ end
155
+
156
+ name ||= "amq.#{type}"
157
+ puts "Exchange [#{type}::#{name}]: #{args.inspect}" if @debug > 3
158
+ (@exchanges||={})[name] ||= ::Carrot::AMQP::Exchange.new client, type, name, *args
159
+ end
160
+
161
+ def queue
162
+ return @queue unless @queue.nil?
163
+ puts "Queue [#{@queue_name}]: #{@queue_config.inspect}" if @debug > 0
164
+ @queue ||= client.queue(@queue_name, @queue_config)
165
+ end
166
+
167
+ def client
168
+ return @client unless @client.nil?
169
+ puts "Client [amqp]: #{@connect_options.inspect}" if @debug > 0
170
+ @client ||= Carrot.new(@connect_options)
171
+ end
172
+
173
+ end
174
+
175
+ class AmqpMessage < Emissary::Message
176
+ attr_reader :command
177
+ attr_accessor :destination, :delivery_tag
178
+
179
+ def initialize(data, queue_name = nil)
180
+ data[:data] = data.delete(:body) unless (data[:data] && !data[:body])
181
+
182
+ super(data)
183
+
184
+ @delivery_tag ||= (data[:headers][:delivery_tag] rescue nil)
185
+ @destination ||= (data[:headers][:destination] rescue nil) || queue_name || routing_key
186
+
187
+ @command = "MESSAGE"
188
+ end
189
+
190
+ alias :body :data
191
+
192
+ def headers
193
+ super.merge({
194
+ :destination => routing_key,
195
+ :delivery_tag => @delivery_tag
196
+ })
197
+ end
198
+
199
+ def matches_subscription?(subscription)
200
+ # use routing key first, otherwise, use the defined destination value
201
+ destination = subscription.subscribe_headers[:routing_key] || subscription.destination.value.to_s
202
+
203
+ if destination.match(/(\#|\*)/)
204
+ dest_regex = ::Regexp.new(destination.gsub('.*', '[.][^.]+').gsub(/\.\#.*/, '[.].*'))
205
+ !!(headers[:destination].to_s =~ dest_regex)
206
+ else
207
+ !!(headers[:destination].to_s == destination)
208
+ end
209
+ end
210
+ end
211
+
212
+ end
213
+ end
214
+ end
215
+
@@ -6,6 +6,7 @@ require 'base64'
6
6
  require 'cgi'
7
7
  require 'time'
8
8
  require 'uri'
9
+ require 'rexml/document'
9
10
 
10
11
  require 'activemessaging/adapters/base'
11
12
 
@@ -204,8 +205,7 @@ module ActiveMessaging
204
205
 
205
206
  # Sign the string
206
207
  sorted_params = params.sort_by { |key,value| key.downcase }
207
- joined_params = sorted_params.collect { |key, value| key.to_s + value.to_s }
208
- string_to_sign = joined_params.to_s
208
+ string_to_sign = sorted_params.collect { |key, value| key.to_s + value.to_s }.join()
209
209
  digest = OpenSSL::Digest::Digest.new('sha1')
210
210
  hmac = OpenSSL::HMAC.digest(digest, @secret_access_key, string_to_sign)
211
211
  params['Signature'] = Base64.encode64(hmac).chomp
@@ -417,4 +417,4 @@ module ActiveMessaging
417
417
 
418
418
  end
419
419
  end
420
- end
420
+ end
@@ -22,7 +22,7 @@ module ActiveMessaging
22
22
  @host = cfg[:host] || 'localhost'
23
23
  @port = cfg[:port] || 11300
24
24
 
25
- @connection = ::Beanstalk::Pool.new("#{@host}:#{@port}")
25
+ @connection = ::Beanstalk::Pool.new(["#{@host}:#{@port}"])
26
26
  end
27
27
 
28
28
  def disconnect
@@ -9,11 +9,12 @@ module ActiveMessaging
9
9
  class Connection < ActiveMessaging::Adapters::BaseConnection
10
10
  register :stomp
11
11
 
12
- attr_accessor :stomp_connection, :retryMax, :deadLetterQueue, :configuration
12
+ attr_accessor :stomp_connection, :retryMax, :deadLetterQueue, :configuration, :deadLetterQueuePrefix
13
13
 
14
14
  def initialize(cfg)
15
15
  @retryMax = cfg[:retryMax] || 0
16
16
  @deadLetterQueue = cfg[:deadLetterQueue] || nil
17
+ @deadLetterQueuePrefix = cfg[:deadLetterQueuePrefix] || nil
17
18
 
18
19
  cfg[:login] ||= ""
19
20
  cfg[:passcode] ||= ""
@@ -31,7 +32,22 @@ module ActiveMessaging
31
32
  connect_headers['client-id'] = cfg[:clientId] if cfg[:clientId]
32
33
  @stomp_connection = ::Stomp::Connection.new(cfg[:login],cfg[:passcode],cfg[:host],cfg[:port].to_i,cfg[:reliable],cfg[:reconnectDelay], connect_headers)
33
34
  end
34
-
35
+
36
+ # Checks if the connection supports dead letter queues
37
+ def supports_dlq?
38
+ !@deadLetterQueue.nil? || !@deadLetterQueuePrefix.nil?
39
+ end
40
+
41
+ # add the dead letter queue prefix to the destination
42
+ def add_dlq_prefix(destination)
43
+ if (ri = destination.rindex("/"))
44
+ destination.clone.insert(ri + 1, @deadLetterQueuePrefix)
45
+ else
46
+ @deadLetterQueuePrefix + destination
47
+ end
48
+
49
+ end
50
+
35
51
  # called to cleanly get rid of connection
36
52
  def disconnect
37
53
  @stomp_connection.disconnect
@@ -80,10 +96,9 @@ module ActiveMessaging
80
96
  end
81
97
  end
82
98
 
83
- def unreceive message, headers={}
99
+ def unreceive message, headers={}
84
100
  retry_count = message.headers['a13g-retry-count'].to_i || 0
85
101
  transaction_id = "transaction-#{message.headers['message-id']}-#{retry_count}"
86
-
87
102
  # start a transaction, send the message back to the original destination
88
103
  @stomp_connection.begin(transaction_id)
89
104
  begin
@@ -91,11 +106,24 @@ module ActiveMessaging
91
106
  if @retryMax > 0
92
107
  retry_headers = message.headers.stringify_keys
93
108
  retry_headers['transaction']= transaction_id
94
- retry_headers.delete('content-length')
95
- retry_headers.delete('content-type')
96
-
109
+ content_type_header = retry_headers.delete('content-type')
110
+ content_length_header = retry_headers.delete('content-length')
111
+ # If the content-length header in the original message is nil
112
+ # then we need to set the :suppress_content_length option so
113
+ # that the stomp client does not set the content-length of the
114
+ # retried message. This option will allow ActiveMQ to interpret the
115
+ # message as a TextMessage.
116
+ # This is somewhat of a hack because the setting of the :suppress_content_length
117
+ # header is usually done in the messaging.rb and is removed by the time
118
+ # the unreceive message is called. So I am making some assumptions here
119
+ # on whether or not to set the option
120
+ if content_type_header and content_type_header.include?('text/plain') && content_length_header.nil?
121
+ retry_headers[:suppress_content_length] = true
122
+ end
123
+
97
124
  retry_destination = retry_headers.delete('destination')
98
-
125
+ retry_destination = headers[:destination] if headers[:destination]
126
+
99
127
  if retry_count < @retryMax
100
128
  # now send the message back to the destination
101
129
  # set the headers for message id, priginal message id, and retry count
@@ -108,15 +136,23 @@ module ActiveMessaging
108
136
  retry_headers['a13g-retry-count'] = retry_count + 1
109
137
 
110
138
  # send the updated message to retry in the same transaction
139
+ logger.warn "retrying message on #{retry_destination}"
111
140
  self.stomp_publish(retry_destination, message.body, retry_headers)
112
141
 
113
- elsif retry_count >= @retryMax && @deadLetterQueue
142
+ elsif retry_count >= @retryMax && supports_dlq?
114
143
  # send the 'poison pill' message to the dead letter queue - make it persistent by default
115
- retry_headers['a13g-original-destination'] = retry_headers.delete('destination')
144
+ retry_headers['a13g-original-destination'] = retry_destination #retry_headers.delete('destination')
116
145
  retry_headers['persistent'] = true
117
146
  retry_headers.delete('message-id')
118
-
119
- self.stomp_publish(@deadLetterQueue, message.body, retry_headers)
147
+
148
+ # If the prefix option is set then put the prefix after the /queue/ or /topic/
149
+ if (@deadLetterQueuePrefix)
150
+ dlq = add_dlq_prefix(retry_destination)
151
+ else
152
+ dlq = @deadLetterQueue
153
+ end
154
+ logger.warn "putting message on DLQ: #{dlq}"
155
+ self.stomp_publish(dlq, message.body, retry_headers)
120
156
  end
121
157
 
122
158
  end
@@ -164,4 +200,4 @@ module ActiveMessaging
164
200
 
165
201
  end
166
202
  end
167
- end
203
+ end
@@ -0,0 +1,94 @@
1
+ #
2
+ # This is meant to avoid the need to use a broker in development, and generally make development mode easier
3
+ #
4
+ module ActiveMessaging
5
+ module Adapters
6
+ module Synch
7
+
8
+ class Connection < ActiveMessaging::Adapters::BaseConnection
9
+ register :synch
10
+
11
+ #configurable params
12
+ attr_accessor :configuration, :max_process, :processing_pids, :use_fork
13
+
14
+ #generic init method needed by a13g
15
+ def initialize cfg
16
+ ActiveMessaging.logger.debug "ActiveMessaging::Adapters::Synch::Connection.initialize: #{cfg.inspect}"
17
+ @configuration = cfg
18
+
19
+ @use_fork = !!@configuration[:use_fork]
20
+
21
+ # max at once
22
+ @max_process = 10
23
+ # keep track of the processes running
24
+ @processing_pids = {}
25
+
26
+ if use_fork
27
+ Thread.new {
28
+ watch_processes
29
+ }
30
+ end
31
+ end
32
+
33
+ def watch_processes
34
+ while true
35
+ begin
36
+ pid = Process.wait(0, Process::WNOHANG)
37
+ if m = processing_pids.delete(pid)
38
+ ActiveMessaging.logger.debug "ActiveMessaging:synch - processing complete for pid (#{pid}):\n\t#{m}"
39
+ end
40
+ sleep(0.5)
41
+ rescue
42
+ end
43
+ end
44
+ end
45
+
46
+ def send destination_name, message_body, message_headers={}
47
+ message = Message.new(message_body, 'id', message_headers, destination_name, 'MESSAGE')
48
+
49
+ if use_fork
50
+
51
+ if processing_pids.size > max_process
52
+ ActiveMessaging.logger.debug "ActiveMessaging:synch too many processes: #{processing_pids.size} > #{max_process}"
53
+ sleep(0.5)
54
+ end
55
+
56
+ pid = fork {
57
+ ActiveMessaging.logger.debug "\n-------------------- ActiveMessaging:synch start fork dispath (#{Process.pid}) --------------------"
58
+ ActiveMessaging::Gateway.prepare_application
59
+ ActiveMessaging::Gateway._dispatch(message)
60
+ ActiveMessaging::Gateway.reset_application
61
+ ActiveMessaging.logger.debug "-------------------- ActiveMessaging:synch end fork dispath (#{Process.pid})--------------------\n"
62
+ }
63
+
64
+ Process.detach(pid)
65
+ processing_pids[pid] = "Destination: #{destination_name}, Message: #{message_body}"
66
+
67
+ else
68
+
69
+ ActiveMessaging.logger.debug "\n-------------------- ActiveMessaging:synch before dispath --------------------"
70
+ ActiveMessaging::Gateway.prepare_application
71
+ ActiveMessaging::Gateway._dispatch(message)
72
+ ActiveMessaging::Gateway.reset_application
73
+ ActiveMessaging.logger.debug "-------------------- ActiveMessaging:synch after dispath --------------------\n"
74
+
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ class Message < ActiveMessaging::BaseMessage
82
+ attr_accessor :command
83
+
84
+ def initialize body, id, headers, destination, command='MESSAGE'
85
+ # ActiveMessaging.logger.debug "Message headers:#{headers.inspect}, id:#{id}, body:#{body}, destination:#{destination}, command:#{command}"
86
+ @headers, @body, @destination, @command = headers, body, destination, command
87
+ headers['destination'] = destination
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -111,7 +111,9 @@ module ActiveMessaging
111
111
  def connection broker_name='default'
112
112
  return @@connections[broker_name] if @@connections.has_key?(broker_name)
113
113
  config = load_connection_configuration(broker_name)
114
- @@connections[broker_name] = Gateway.adapters[config[:adapter]].new(config)
114
+ adapter_class = Gateway.adapters[config[:adapter]]
115
+ raise "Unknown messaging adapter #{config[:adapter].inspect}!" if adapter_class.nil?
116
+ @@connections[broker_name] = adapter_class.new(config)
115
117
  end
116
118
 
117
119
  def register_adapter adapter_name, adapter_class
@@ -188,16 +190,12 @@ module ActiveMessaging
188
190
  end
189
191
 
190
192
  def prepare_application
191
- if defined? Rails
192
- # Dispatcher.prepare_application_for_dispatch
193
+ if defined? ActiveRecord
193
194
  ActiveRecord::Base.verify_active_connections!
194
195
  end
195
196
  end
196
197
 
197
198
  def reset_application
198
- if defined? Rails
199
- # Dispatcher.reset_application_after_dispatch
200
- end
201
199
  end
202
200
 
203
201
  def dispatch(message)
@@ -210,6 +208,7 @@ module ActiveMessaging
210
208
  ActiveMessaging.logger.error exc.backtrace.join("\n\t")
211
209
  raise exc
212
210
  ensure
211
+ ActiveMessaging.logger.flush rescue nil
213
212
  reset_application
214
213
  end
215
214
  }
@@ -223,9 +222,9 @@ module ActiveMessaging
223
222
  if message.matches_subscription?(subscription) then
224
223
  processed = true
225
224
  routing = {
226
- :receiver=>subscription.processor_class,
227
- :destination=>subscription.destination,
228
- :direction => :incoming
225
+ :receiver => subscription.processor_class,
226
+ :destination => subscription.destination,
227
+ :direction => :incoming
229
228
  }
230
229
  begin
231
230
  execute_filter_chain(:incoming, message, routing) do |m|
@@ -358,11 +357,11 @@ module ActiveMessaging
358
357
  end
359
358
 
360
359
  def load_connection_configuration(label='default')
361
- @broker_yml = YAML::load(ERB.new(IO.read(File.join(APP_ROOT, 'config', 'broker.yml'))).result) if @broker_yml.nil?
360
+ @broker_yml = YAML::load(ERB.new(IO.read(File.join(ActiveMessaging.app_root, 'config', 'broker.yml'))).result) if @broker_yml.nil?
362
361
  if label == 'default'
363
- config = @broker_yml[APP_ENV].symbolize_keys
362
+ config = @broker_yml[ActiveMessaging.app_env].symbolize_keys
364
363
  else
365
- config = @broker_yml[APP_ENV][label].symbolize_keys
364
+ config = @broker_yml[ActiveMessaging.app_env][label].symbolize_keys
366
365
  end
367
366
  config[:adapter] = config[:adapter].to_sym if config[:adapter]
368
367
  config[:adapter] ||= :stomp
@@ -13,8 +13,7 @@ module ActiveMessaging
13
13
  end
14
14
 
15
15
  def logger()
16
- @@logger = ActiveMessaging.logger unless defined?(@@logger)
17
- @@logger
16
+ @@logger ||= ActiveMessaging.logger
18
17
  end
19
18
 
20
19
  def on_message(message)
@@ -37,7 +36,7 @@ module ActiveMessaging
37
36
  logger.error "Processor:process! - AbortMessageException caught."
38
37
  raise rpe
39
38
  rescue Object=>ex
40
- logger.error "Processor:process! - error in on_error, will propagate no further: #{ex.message}"
39
+ logger.error "Processor:process! - error in on_error, will propagate no further: #{ex.message}\n\t#{ex.backtrace.join("\n\t")}"
41
40
  end
42
41
  end
43
42
 
@@ -0,0 +1,22 @@
1
+ require 'logger'
2
+ require 'rails'
3
+ require 'activemessaging'
4
+
5
+ module ActiveMessaging
6
+ class Railtie < Rails::Railtie
7
+
8
+ initializer 'activemessaging.initialize' do
9
+
10
+ ActiveMessaging.load_activemessaging
11
+
12
+ if defined? Rails
13
+ ActiveMessaging.logger.info "ActiveMessaging: Rails available: Adding dispatcher prepare callback."
14
+ ActionDispatch::Callbacks.to_prepare :activemessaging do
15
+ ActiveMessaging.reload_activemessaging
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
@@ -1,34 +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
-
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
+
File without changes
data/test/stomp_test.rb CHANGED
@@ -69,11 +69,14 @@ class StompTest < Test::Unit::TestCase
69
69
  :port=> "61613",
70
70
  :reliable=>FALSE,
71
71
  :reconnectDelay=> 5,
72
- :clientId=> 'cid' }
72
+ :clientId=> 'cid',
73
+ :deadLetterQueuePrefix=>"DLQ."}
73
74
 
74
75
  @connection = ActiveMessaging::Adapters::Stomp::Connection.new(i)
75
76
  assert_equal 4, @connection.retryMax
76
77
  assert_equal '/queue/dlq', @connection.deadLetterQueue
78
+ assert_equal "DLQ.", @connection.deadLetterQueuePrefix
79
+ assert_equal true, @connection.supports_dlq?
77
80
  end
78
81
 
79
82
  def test_disconnect
@@ -123,9 +126,30 @@ class StompTest < Test::Unit::TestCase
123
126
  @connection = ActiveMessaging::Adapters::Stomp::Connection.new({:retryMax=>4, :deadLetterQueue=>'/queue/dlq'})
124
127
  @connection.stomp_connection.receive = @message
125
128
  m = @connection.receive
129
+ m.headers["a13g-retry-count"] = 5
126
130
  @connection.unreceive m, {:ack=>'client'}
127
131
  end
128
132
 
133
+ def test_unreceive_with_dlq_prefix
134
+ @connection = ActiveMessaging::Adapters::Stomp::Connection.new({:retryMax=>4, :deadLetterQueuePrefix=>'DLQ.'})
135
+ @connection.stomp_connection.receive = @message
136
+ m = @connection.receive
137
+ m.headers["a13g-retry-count"] = 5
138
+ @connection.unreceive m, {:ack=>'client', :destination=>"/queue/myqueue"}
139
+ end
140
+
141
+ def test_add_dlq_prefix
142
+ @connection = ActiveMessaging::Adapters::Stomp::Connection.new({:deadLetterQueuePrefix=>'DLQ.'})
143
+ dlq = @connection.add_dlq_prefix("/queue/myqueue")
144
+ assert_equal "/queue/DLQ.myqueue", dlq
145
+ dlq = @connection.add_dlq_prefix("/queue/something/myqueue")
146
+ assert_equal "/queue/something/DLQ.myqueue", dlq
147
+ dlq = @connection.add_dlq_prefix("/topic/myqueue")
148
+ assert_equal "/topic/DLQ.myqueue", dlq
149
+ dlq = @connection.add_dlq_prefix("myqueue")
150
+ assert_equal "DLQ.myqueue", dlq
151
+ end
152
+
129
153
  end
130
154
 
131
155
  end # if loaded
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activemessaging
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ hash: 61
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 8
9
+ - 1
10
+ version: 0.8.1
5
11
  platform: ruby
6
12
  authors:
7
13
  - Jon Tirsen
@@ -14,20 +20,26 @@ autorequire:
14
20
  bindir: bin
15
21
  cert_chain: []
16
22
 
17
- date: 2010-04-08 00:00:00 -04:00
23
+ date: 2011-08-15 00:00:00 -04:00
18
24
  default_executable:
19
25
  dependencies:
20
26
  - !ruby/object:Gem::Dependency
21
27
  name: activesupport
22
- type: :runtime
23
- version_requirement:
24
- version_requirements: !ruby/object:Gem::Requirement
28
+ prerelease: false
29
+ requirement: &id001 !ruby/object:Gem::Requirement
30
+ none: false
25
31
  requirements:
26
32
  - - ">="
27
33
  - !ruby/object:Gem::Version
34
+ hash: 23
35
+ segments:
36
+ - 1
37
+ - 0
38
+ - 0
28
39
  version: 1.0.0
29
- version:
30
- description: ActiveMessaging is an attempt to bring the simplicity and elegance of rails development to the world of messaging. Messaging, (or event-driven architecture) is widely used for enterprise integration, with frameworks such as Java's JMS, and products such as ActiveMQ, Tibco, IBM MQSeries, etc.
40
+ type: :runtime
41
+ version_requirements: *id001
42
+ description: ActiveMessaging is an attempt to bring the simplicity and elegance of rails development to the world of messaging. Messaging, (or event-driven architecture) is widely used for enterprise integration, with frameworks such as Java's JMS, and products such as ActiveMQ, Tibco, IBM MQSeries, etc. Now supporting Rails 3 as of version 0.8.0.
31
43
  email: activemessaging-discuss@googlegroups.com
32
44
  executables: []
33
45
 
@@ -68,12 +80,14 @@ files:
68
80
  - init.rb
69
81
  - lib/activemessaging.rb
70
82
  - lib/activemessaging/adapter.rb
83
+ - lib/activemessaging/adapters/amqp.rb
71
84
  - lib/activemessaging/adapters/asqs.rb
72
85
  - lib/activemessaging/adapters/base.rb
73
86
  - lib/activemessaging/adapters/beanstalk.rb
74
87
  - lib/activemessaging/adapters/jms.rb
75
88
  - lib/activemessaging/adapters/reliable_msg.rb
76
89
  - lib/activemessaging/adapters/stomp.rb
90
+ - lib/activemessaging/adapters/synch.rb
77
91
  - lib/activemessaging/adapters/test.rb
78
92
  - lib/activemessaging/adapters/wmq.rb
79
93
  - lib/activemessaging/base_message.rb
@@ -82,11 +96,11 @@ files:
82
96
  - lib/activemessaging/message_sender.rb
83
97
  - lib/activemessaging/named_base.rb
84
98
  - lib/activemessaging/processor.rb
85
- - lib/activemessaging/support.rb
99
+ - lib/activemessaging/railtie.rb
86
100
  - lib/activemessaging/test_helper.rb
87
101
  - lib/activemessaging/trace_filter.rb
102
+ - lib/tasks/start_consumers.rake
88
103
  - poller.rb
89
- - tasks/start_consumers.rake
90
104
  - test/all_tests.rb
91
105
  - test/app/config/broker.yml
92
106
  - test/asqs_test.rb
@@ -103,26 +117,32 @@ homepage: http://github.com/kookster/activemessaging
103
117
  licenses: []
104
118
 
105
119
  post_install_message:
106
- rdoc_options:
107
- - --charset=UTF-8
120
+ rdoc_options: []
121
+
108
122
  require_paths:
109
123
  - lib
110
124
  required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
111
126
  requirements:
112
127
  - - ">="
113
128
  - !ruby/object:Gem::Version
129
+ hash: 3
130
+ segments:
131
+ - 0
114
132
  version: "0"
115
- version:
116
133
  required_rubygems_version: !ruby/object:Gem::Requirement
134
+ none: false
117
135
  requirements:
118
136
  - - ">="
119
137
  - !ruby/object:Gem::Version
138
+ hash: 3
139
+ segments:
140
+ - 0
120
141
  version: "0"
121
- version:
122
142
  requirements: []
123
143
 
124
144
  rubyforge_project:
125
- rubygems_version: 1.3.5
145
+ rubygems_version: 1.4.2
126
146
  signing_key:
127
147
  specification_version: 3
128
148
  summary: Official activemessaging gem, now hosted on github.com/kookster. (kookster prefix temporary)
@@ -1,17 +0,0 @@
1
- if defined? Rails
2
- ActiveMessaging.logger.debug "Rails available: Adding reload hooks."
3
- require 'dispatcher' unless defined?(::Dispatcher)
4
- ::Dispatcher.class_eval do
5
-
6
- def self.prepare_application_for_dispatch
7
- disp = new(STDOUT)
8
- disp.run_callbacks :before_dispatch
9
- end
10
-
11
- def self.reset_application_after_dispatch
12
- disp = new(STDOUT)
13
- disp.run_callbacks :after_dispatch, :enumerator => :reverse_each
14
- end
15
-
16
- end
17
- end