activemessaging 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/Rakefile +50 -0
  2. data/generators/a13g_test_harness/a13g_test_harness_generator.rb +19 -0
  3. data/generators/a13g_test_harness/templates/active_messaging_test.rhtml +13 -0
  4. data/generators/a13g_test_harness/templates/active_messaging_test_controller.rb +29 -0
  5. data/generators/a13g_test_harness/templates/index.rhtml +17 -0
  6. data/generators/filter/USAGE +0 -0
  7. data/generators/filter/filter_generator.rb +19 -0
  8. data/generators/filter/templates/filter.rb +12 -0
  9. data/generators/filter/templates/filter_test.rb +28 -0
  10. data/generators/processor/USAGE +8 -0
  11. data/generators/processor/processor_generator.rb +31 -0
  12. data/generators/processor/templates/application.rb +18 -0
  13. data/generators/processor/templates/broker.yml +79 -0
  14. data/generators/processor/templates/jruby_poller +117 -0
  15. data/generators/processor/templates/messaging.rb +12 -0
  16. data/generators/processor/templates/poller +23 -0
  17. data/generators/processor/templates/poller.rb +23 -0
  18. data/generators/processor/templates/processor.rb +8 -0
  19. data/generators/processor/templates/processor_test.rb +20 -0
  20. data/generators/tracer/USAGE +8 -0
  21. data/generators/tracer/templates/controller.rb +14 -0
  22. data/generators/tracer/templates/helper.rb +2 -0
  23. data/generators/tracer/templates/index.rhtml +4 -0
  24. data/generators/tracer/templates/layout.rhtml +16 -0
  25. data/generators/tracer/templates/trace_processor.rb +100 -0
  26. data/generators/tracer/tracer_generator.rb +25 -0
  27. data/lib/activemessaging.rb +133 -0
  28. data/lib/activemessaging/adapter.rb +21 -0
  29. data/lib/activemessaging/adapters/asqs.rb +412 -0
  30. data/lib/activemessaging/adapters/base.rb +82 -0
  31. data/lib/activemessaging/adapters/jms.rb +237 -0
  32. data/lib/activemessaging/adapters/reliable_msg.rb +190 -0
  33. data/lib/activemessaging/adapters/stomp.rb +99 -0
  34. data/lib/activemessaging/adapters/test.rb +155 -0
  35. data/lib/activemessaging/adapters/wmq.rb +202 -0
  36. data/lib/activemessaging/filter.rb +29 -0
  37. data/lib/activemessaging/gateway.rb +422 -0
  38. data/lib/activemessaging/message_sender.rb +30 -0
  39. data/lib/activemessaging/named_base.rb +54 -0
  40. data/lib/activemessaging/processor.rb +45 -0
  41. data/lib/activemessaging/support.rb +17 -0
  42. data/lib/activemessaging/test_helper.rb +194 -0
  43. data/lib/activemessaging/trace_filter.rb +34 -0
  44. data/messaging.rb.example +5 -0
  45. data/tasks/start_consumers.rake +8 -0
  46. metadata +123 -0
@@ -0,0 +1,30 @@
1
+ require 'logger'
2
+
3
+ module ActiveMessaging
4
+
5
+ # This is a module so that we can send messages from (for example) web page controllers, or can receive a single message
6
+ module MessageSender
7
+
8
+ def self.included(included_by)
9
+ class << included_by
10
+ def publishes_to destination_name
11
+ Gateway.find_destination destination_name
12
+ end
13
+
14
+ def receives_from destination_name
15
+ Gateway.find_destination destination_name
16
+ end
17
+ end
18
+ end
19
+
20
+ def publish destination_name, message, headers={}, timeout=10
21
+ Gateway.publish(destination_name, message, self.class, headers, timeout)
22
+ end
23
+
24
+ def receive destination_name, headers={}, timeout=10
25
+ Gateway.receive(destination_name, self.class, headers, timeout)
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,54 @@
1
+ #Adapter to rubigen / rails
2
+
3
+ if defined?(Rails)
4
+ class NamedBase < Rails::Generator::NamedBase
5
+ end
6
+ else
7
+ class NamedBase < RubiGen::Base
8
+ attr_reader :name, :class_name, :singular_name, :plural_name
9
+ attr_reader :class_path, :file_path, :class_nesting, :class_nesting_depth
10
+ alias_method :file_name, :singular_name
11
+ alias_method :actions, :args
12
+
13
+ def initialize(runtime_args, runtime_options={})
14
+ super
15
+
16
+ base_name = self.args.first
17
+ assign_names!(base_name)
18
+ end
19
+
20
+ protected
21
+
22
+ def assign_names!(name)
23
+ @name = name
24
+ base_name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(@name)
25
+ @class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name)
26
+ if @class_nesting.empty?
27
+ @class_name = @class_name_without_nesting
28
+ else
29
+ @table_name = @class_nesting.underscore << "_" << @table_name
30
+ @class_name = "#{@class_nesting}::#{@class_name_without_nesting}"
31
+ end
32
+ end
33
+
34
+ # Extract modules from filesystem-style or ruby-style path:
35
+ # good/fun/stuff
36
+ # Good::Fun::Stuff
37
+ # produce the same results.
38
+ def extract_modules(name)
39
+ modules = name.include?('/') ? name.split('/') : name.split('::')
40
+ name = modules.pop
41
+ path = modules.map { |m| m.underscore }
42
+ file_path = (path + [name.underscore]).join('/')
43
+ nesting = modules.map { |m| m.camelize }.join('::')
44
+ [name, path, file_path, nesting, modules.size]
45
+ end
46
+
47
+ def inflect_names(name)
48
+ camel = name.camelize
49
+ under = camel.underscore
50
+ plural = under.pluralize
51
+ [camel, under, plural]
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ # 'abstract' base class for ActiveMessaging processor classes
2
+ module ActiveMessaging
3
+
4
+ class Processor
5
+ include MessageSender
6
+
7
+ attr_reader :message
8
+
9
+ class<<self
10
+ def subscribes_to destination_name, headers={}
11
+ ActiveMessaging::Gateway.subscribe_to destination_name, self, headers
12
+ end
13
+ end
14
+
15
+ def logger()
16
+ @@logger = ActiveMessaging.logger unless defined?(@@logger)
17
+ @@logger
18
+ end
19
+
20
+ def on_message(message)
21
+ raise NotImplementedError.new("Implement the on_message method in your own processor class that extends ActiveMessaging::Processor")
22
+ end
23
+
24
+ def on_error(exception)
25
+ raise exception
26
+ end
27
+
28
+ # Bind the processor to the current message so that the processor could
29
+ # potentially access headers and other attributes of the message
30
+ def process!(message)
31
+ @message = message
32
+ return on_message(message.body)
33
+ rescue Object=>err
34
+ begin
35
+ on_error(err)
36
+ rescue ActiveMessaging::AbortMessageException => rpe
37
+ logger.error "Processor:process! - AbortMessageException caught."
38
+ raise rpe
39
+ rescue Object=>ex
40
+ logger.error "Processor:process! - error in on_error, will propagate no further: #{ex.message}"
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,17 @@
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
@@ -0,0 +1,194 @@
1
+ require 'test/unit'
2
+ #require "#{File.dirname(__FILE__)}/trace_filter"
3
+
4
+
5
+ module ActiveMessaging #:nodoc:
6
+ @@logger = nil
7
+
8
+ # def self.reload_activemessaging
9
+ # end
10
+
11
+ def self.logger
12
+ @@logger ||= MockLogger.new
13
+ @@logger
14
+ end
15
+
16
+ class AbortMessageException < Exception #:nodoc:
17
+ end
18
+
19
+ class StopFilterException < Exception #:nodoc:
20
+ end
21
+
22
+ class Gateway
23
+
24
+ def self.reset
25
+ unsubscribe
26
+ disconnect
27
+ @@filters = []
28
+ @@subscriptions = {}
29
+ @@named_destinations = {}
30
+ @@processor_groups = {}
31
+ @@current_processor_group = nil
32
+ @@connections = {}
33
+ end
34
+ end
35
+
36
+ module MessageSender
37
+
38
+ @@__a13g_initialized__ = false
39
+ def publish_with_reset(destination_name, message, headers={}, timeout=10)
40
+ unless @@__a13g_initialized__
41
+ ActiveMessaging.reload_activemessaging
42
+ @@__a13g_initialized__ = true
43
+ end
44
+ publish_without_reset(destination_name, message, headers, timeout)
45
+ end
46
+
47
+ alias_method_chain :publish, :reset
48
+
49
+ end
50
+
51
+ class TestMessage
52
+ attr_reader :headers
53
+ attr_accessor :body
54
+
55
+ def initialize(destination, headers = {}, body = "")
56
+ @headers, @body = headers, body
57
+ @headers['destination'] = destination
58
+ end
59
+
60
+ def command
61
+ "MESSAGE"
62
+ end
63
+ end
64
+
65
+ module TestHelper
66
+
67
+ # #Many thanks must go to the ActiveRecord fixture code
68
+ # #for showing how to properly alias setup and teardown
69
+ # def self.included(base)
70
+ # base.extend(ClassMethods)
71
+ #
72
+ # class << base
73
+ # alias_method_chain :method_added, :a13g
74
+ # end
75
+ #
76
+ # end
77
+
78
+ # module ClassMethods
79
+ #
80
+ # def method_added_with_a13g(method)
81
+ # return if @__a13g_disable_method_added__
82
+ # @__a13g_disable_method_added__ = true
83
+ #
84
+ # case method.to_s
85
+ # when 'setup'
86
+ # unless method_defined?(:setup_without_a13g)
87
+ # alias_method :setup_without_a13g, :setup
88
+ # define_method(:full_setup) do
89
+ # setup_with_a13g
90
+ # setup_without_a13g
91
+ # end
92
+ # end
93
+ # alias_method :setup, :full_setup
94
+ # when 'teardown'
95
+ # unless method_defined?(:teardown_without_a13g)
96
+ # alias_method :teardown_without_a13g, :teardown
97
+ # define_method(:full_teardown) do
98
+ # teardown_without_a13g
99
+ # teardown_with_a13g
100
+ # end
101
+ # end
102
+ # alias_method :teardown, :full_teardown
103
+ # end
104
+ #
105
+ # method_added_without_a13g(method)
106
+ #
107
+ # @__a13g_disable_method_added__ = false
108
+ # end
109
+ #
110
+ # end
111
+
112
+ # def setup_with_a13g
113
+ # ActiveMessaging.reload_activemessaging
114
+ # end
115
+ #
116
+ # def teardown_with_a13g
117
+ # ActiveMessaging::Gateway.reset
118
+ # end
119
+
120
+ def mock_publish destination, body, publisher=nil, headers={}
121
+ ActiveMessaging::Gateway.publish destination, body, publisher, headers
122
+ end
123
+
124
+ def assert_message destination, body
125
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
126
+ error_message = <<-EOF
127
+ Message for '#{destination}' with '#{body}' is not present.
128
+ Messages:
129
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
130
+ EOF
131
+ assert ActiveMessaging::Gateway.connection.find_message(destination, body), error_message
132
+ end
133
+
134
+ def assert_no_message_with destination, body
135
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
136
+ error_message = <<-EOF
137
+ Message for '#{destination}' with '#{body}' is present.
138
+ Messages:
139
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
140
+ EOF
141
+ assert_nil ActiveMessaging::Gateway.connection('default').find_message(destination, body), error_message
142
+ end
143
+
144
+ def assert_no_messages destination
145
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
146
+ error_message = <<-EOF
147
+ Expected no messages.
148
+ Messages:
149
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
150
+ EOF
151
+ assert_equal [], ActiveMessaging::Gateway.connection('default').all_messages, error_message
152
+ end
153
+
154
+ def assert_subscribed destination
155
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
156
+ error_message = <<-EOF
157
+ Not subscribed to #{destination}.
158
+ Subscriptions:
159
+ #{ActiveMessaging::Gateway.connection('default').subscriptions.inspect}
160
+ EOF
161
+ assert ActiveMessaging::Gateway.connection('default').find_subscription(destination), error_message
162
+ end
163
+
164
+ def assert_not_subscribed destination
165
+ destination = ActiveMessaging::Gateway.find_destination(destination).value
166
+ error_message = <<-EOF
167
+ Subscribed to #{destination}.
168
+ Subscriptions:
169
+ #{ActiveMessaging::Gateway.connection('default').subscriptions.inspect}
170
+ EOF
171
+ assert_nil ActiveMessaging::Gateway.connection('default').find_subscription(destination), error_message
172
+ end
173
+
174
+ def assert_has_messages destination
175
+ destination_name = ActiveMessaging::Gateway.find_destination(destination).value
176
+ error_message = <<-EOF
177
+ No messages for #{destination_name}.
178
+ All messages:
179
+ #{ActiveMessaging::Gateway.connection('default').all_messages.inspect}
180
+ EOF
181
+ destination = ActiveMessaging::Gateway.connection('default').find_destination destination_name
182
+ assert !destination.nil? && !destination.messages.empty?, error_message
183
+ end
184
+ end
185
+
186
+ class MockLogger
187
+ def error(*args) ; end
188
+ def warn(*args) ; end
189
+ def info(*args) ; end
190
+ def debug(*args) ; end
191
+ end
192
+
193
+ end
194
+
@@ -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,5 @@
1
+
2
+ ActiveMessaging::Dispatcher.define do |s|
3
+ s.queue :orders, '/queue/Orders'
4
+ s.queue :completed, '/queue/CompletedItems'
5
+ end
@@ -0,0 +1,8 @@
1
+ namespace "activemessaging" do
2
+
3
+ desc 'Run all consumers'
4
+ task :start_consumers do
5
+ load File.dirname(__FILE__) + '/../poller.rb'
6
+ end
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activemessaging
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ platform: ruby
6
+ authors:
7
+ - jon.tirsen
8
+ - kookster
9
+ - olle.jonsson
10
+ - sylvain.perez
11
+ - anti.god.botherer
12
+ - uwe.kubosch
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2008-08-15 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ type: :runtime
23
+ version_requirement:
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 1.0.0
29
+ version:
30
+ - !ruby/object:Gem::Dependency
31
+ name: rubigen
32
+ type: :runtime
33
+ version_requirement:
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: 1.5.2
39
+ version:
40
+ 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.
41
+ email: activemessaging-discuss@googlegroups.com
42
+ executables: []
43
+
44
+ extensions: []
45
+
46
+ extra_rdoc_files: []
47
+
48
+ files:
49
+ - generators/a13g_test_harness/a13g_test_harness_generator.rb
50
+ - generators/a13g_test_harness/templates/active_messaging_test.rhtml
51
+ - generators/a13g_test_harness/templates/active_messaging_test_controller.rb
52
+ - generators/a13g_test_harness/templates/index.rhtml
53
+ - generators/processor/templates/application.rb
54
+ - generators/processor/templates/poller.rb
55
+ - generators/processor/templates/broker.yml
56
+ - generators/processor/templates/processor.rb
57
+ - generators/processor/templates/jruby_poller
58
+ - generators/processor/templates/poller
59
+ - generators/processor/templates/messaging.rb
60
+ - generators/processor/templates/processor_test.rb
61
+ - generators/processor/processor_generator.rb
62
+ - generators/processor/USAGE
63
+ - generators/tracer/tracer_generator.rb
64
+ - generators/tracer/templates/helper.rb
65
+ - generators/tracer/templates/controller.rb
66
+ - generators/tracer/templates/layout.rhtml
67
+ - generators/tracer/templates/index.rhtml
68
+ - generators/tracer/templates/trace_processor.rb
69
+ - generators/tracer/USAGE
70
+ - generators/filter/filter_generator.rb
71
+ - generators/filter/templates/filter_test.rb
72
+ - generators/filter/templates/filter.rb
73
+ - generators/filter/USAGE
74
+ - lib/activemessaging/message_sender.rb
75
+ - lib/activemessaging/support.rb
76
+ - lib/activemessaging/adapters/reliable_msg.rb
77
+ - lib/activemessaging/adapters/test.rb
78
+ - lib/activemessaging/adapters/jms.rb
79
+ - lib/activemessaging/adapters/asqs.rb
80
+ - lib/activemessaging/adapters/stomp.rb
81
+ - lib/activemessaging/adapters/wmq.rb
82
+ - lib/activemessaging/adapters/base.rb
83
+ - lib/activemessaging/gateway.rb
84
+ - lib/activemessaging/adapter.rb
85
+ - lib/activemessaging/named_base.rb
86
+ - lib/activemessaging/processor.rb
87
+ - lib/activemessaging/trace_filter.rb
88
+ - lib/activemessaging/test_helper.rb
89
+ - lib/activemessaging/filter.rb
90
+ - lib/activemessaging.rb
91
+ - tasks/start_consumers.rake
92
+ - Rakefile
93
+ - messaging.rb.example
94
+ has_rdoc: true
95
+ homepage: http://code.google.com/p/activemessaging/
96
+ licenses: []
97
+
98
+ post_install_message:
99
+ rdoc_options: []
100
+
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: "0"
108
+ version:
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: "0"
114
+ version:
115
+ requirements: []
116
+
117
+ rubyforge_project:
118
+ rubygems_version: 1.3.2
119
+ signing_key:
120
+ specification_version: 2
121
+ summary: 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.
122
+ test_files: []
123
+