message-driver 0.2.2 → 0.3.0

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -17
  3. data/CHANGELOG.md +6 -1
  4. data/Guardfile +3 -3
  5. data/Rakefile +0 -2
  6. data/ci/reset_vhost +5 -0
  7. data/ci/travis_setup +10 -0
  8. data/features/.nav +5 -2
  9. data/features/CHANGELOG.md +6 -1
  10. data/features/amqp_specific_features/declaring_amqp_exchanges.feature +3 -3
  11. data/features/amqp_specific_features/nack_redelivered_messages.feature +2 -2
  12. data/features/amqp_specific_features/server_named_destinations.feature +3 -4
  13. data/features/connecting_to_multiple_brokers.feature +51 -0
  14. data/features/destination_metadata.feature +2 -2
  15. data/features/dynamic_destinations.feature +2 -2
  16. data/features/error_handling.feature +2 -4
  17. data/features/logging.feature +3 -2
  18. data/features/message_consumers/auto_ack_consumers.feature +4 -4
  19. data/features/{message_consumers.feature → message_consumers/basics.feature} +2 -2
  20. data/features/message_consumers/manual_ack_consumers.feature +5 -5
  21. data/features/message_consumers/prefetch_size.feature +4 -4
  22. data/features/message_consumers/transactional_ack_consumers.feature +7 -4
  23. data/features/rabbitmq_specific_features/dead_letter_queueing.feature +3 -3
  24. data/features/step_definitions/dynamic_destinations_steps.rb +2 -2
  25. data/features/step_definitions/logging_steps.rb +5 -1
  26. data/features/step_definitions/message_consumers_steps.rb +1 -1
  27. data/features/step_definitions/steps.rb +13 -4
  28. data/features/support/env.rb +1 -1
  29. data/features/support/test_runner.rb +6 -1
  30. data/lib/message_driver/adapters/base.rb +7 -1
  31. data/lib/message_driver/adapters/bunny_adapter.rb +22 -57
  32. data/lib/message_driver/adapters/in_memory_adapter.rb +3 -2
  33. data/lib/message_driver/adapters/stomp_adapter.rb +6 -6
  34. data/lib/message_driver/broker.rb +80 -19
  35. data/lib/message_driver/client.rb +50 -29
  36. data/lib/message_driver/destination.rb +2 -2
  37. data/lib/message_driver/errors.rb +2 -0
  38. data/lib/message_driver/logging.rb +7 -1
  39. data/lib/message_driver/message.rb +15 -4
  40. data/lib/message_driver/version.rb +1 -1
  41. data/lib/message_driver.rb +12 -5
  42. data/spec/integration/bunny/amqp_integration_spec.rb +15 -20
  43. data/spec/integration/bunny/bunny_adapter_spec.rb +13 -13
  44. data/spec/integration/in_memory/in_memory_adapter_spec.rb +2 -1
  45. data/spec/integration/stomp/stomp_adapter_spec.rb +6 -8
  46. data/spec/spec_helper.rb +9 -0
  47. data/spec/support/shared/adapter_examples.rb +6 -0
  48. data/spec/support/shared/context_examples.rb +2 -0
  49. data/spec/support/shared/destination_examples.rb +2 -0
  50. data/spec/units/message_driver/adapters/base_spec.rb +0 -8
  51. data/spec/units/message_driver/broker_spec.rb +240 -109
  52. data/spec/units/message_driver/client_spec.rb +69 -62
  53. data/spec/units/message_driver/message_spec.rb +59 -22
  54. data/test_lib/broker_config.rb +2 -1
  55. metadata +8 -7
  56. data/lib/bunny/session_patch.rb +0 -19
  57. data/spec/units/message_driver/logging_spec.rb +0 -18
@@ -1,5 +1,4 @@
1
1
  require 'bunny'
2
- require 'bunny/session_patch'
3
2
 
4
3
  module MessageDriver
5
4
  class Broker
@@ -15,8 +14,8 @@ module MessageDriver
15
14
  class Message < MessageDriver::Message::Base
16
15
  attr_reader :delivery_info
17
16
 
18
- def initialize(delivery_info, properties, payload)
19
- super(payload, properties[:headers]||{}, properties)
17
+ def initialize(ctx, delivery_info, properties, payload)
18
+ super(ctx, payload, properties[:headers]||{}, properties)
20
19
  @delivery_info = delivery_info
21
20
  end
22
21
 
@@ -80,13 +79,13 @@ module MessageDriver
80
79
  end
81
80
 
82
81
  def message_count
83
- Client.current_adapter_context.with_channel(false) do |ch|
82
+ adapter.broker.client.current_adapter_context.with_channel(false) do |ch|
84
83
  ch.queue(@name, @dest_options.merge(passive: true)).message_count
85
84
  end
86
85
  end
87
86
 
88
87
  def purge
89
- Client.current_adapter_context.with_channel(false) do |ch|
88
+ adapter.broker.client.current_adapter_context.with_channel(false) do |ch|
90
89
  bunny_queue(ch).purge
91
90
  end
92
91
  end
@@ -149,7 +148,7 @@ module MessageDriver
149
148
  ch.prefetch(options[:prefetch_size])
150
149
  end
151
150
  @bunny_consumer = queue.subscribe(options.merge(manual_ack: true)) do |delivery_info, properties, payload|
152
- Client.with_adapter_context(@sub_ctx) do
151
+ adapter.broker.client.with_adapter_context(@sub_ctx) do
153
152
  message = @sub_ctx.args_to_message(delivery_info, properties, payload)
154
153
  handle_message(message)
155
154
  end
@@ -166,7 +165,7 @@ module MessageDriver
166
165
  when :manual
167
166
  consumer.call(message)
168
167
  when :transactional
169
- Client.with_message_transaction do
168
+ adapter.broker.client.with_message_transaction do
170
169
  consumer.call(message)
171
170
  @sub_ctx.ack_message(message)
172
171
  end
@@ -190,20 +189,22 @@ module MessageDriver
190
189
  end
191
190
  end
192
191
 
193
- def initialize(config)
192
+ def initialize(broker, config)
194
193
  validate_bunny_version
194
+ @broker = broker
195
195
  @config = config
196
- @handle_connection_errors = config.fetch(:handle_connection_errors, true)
197
- initialize_connection
198
196
  end
199
197
 
200
198
  def connection(ensure_started=true)
201
- initialize_connection
202
199
  if ensure_started
203
200
  begin
201
+ @connection ||= Bunny::Session.new(@config)
204
202
  @connection.start
205
203
  rescue *NETWORK_ERRORS => e
206
204
  raise MessageDriver::ConnectionError.new(e.to_s, e)
205
+ rescue => e
206
+ stop
207
+ raise e
207
208
  end
208
209
  end
209
210
  @connection
@@ -212,13 +213,11 @@ module MessageDriver
212
213
  def stop
213
214
  begin
214
215
  super
215
- @connection.close if !@connection.nil? && @connection.open?
216
- rescue *NETWORK_ERRORS => e
216
+ @connection.close if !@connection.nil?
217
+ rescue => e
217
218
  logger.error "error while attempting connection close\n#{exception_to_str(e)}"
218
219
  ensure
219
- conn = @connection
220
220
  @connection = nil
221
- conn.cleanup_threads unless conn.nil?
222
221
  end
223
222
  end
224
223
 
@@ -263,12 +262,6 @@ module MessageDriver
263
262
 
264
263
  def begin_transaction(options={})
265
264
  raise MessageDriver::TransactionError, "you can't begin another transaction, you are already in one!" if in_transaction?
266
- unless is_transactional?
267
- with_channel(false) do |ch|
268
- ch.tx_select
269
- end
270
- @is_transactional = true
271
- end
272
265
  @in_transaction = true
273
266
  end
274
267
 
@@ -396,9 +389,13 @@ module MessageDriver
396
389
 
397
390
  def with_channel(require_commit=true)
398
391
  raise MessageDriver::TransactionRollbackOnly if @rollback_only
399
- raise MessageDriver::Error, "oh nos!" if !valid?
392
+ raise MessageDriver::Error, "this adapter context is not valid!" if !valid?
400
393
  @channel = adapter.connection.create_channel if @channel.nil?
401
394
  reset_channel if @need_channel_reset
395
+ if in_transaction? && !is_transactional?
396
+ @channel.tx_select
397
+ @is_transactional = true
398
+ end
402
399
  handle_errors do
403
400
  result = yield @channel
404
401
  commit_transaction(true) if require_commit && is_transactional? && !in_transaction?
@@ -407,7 +404,7 @@ module MessageDriver
407
404
  end
408
405
 
409
406
  def args_to_message(delivery_info, properties, payload)
410
- Message.new(delivery_info, properties, payload)
407
+ Message.new(self, delivery_info, properties, payload)
411
408
  end
412
409
 
413
410
  private
@@ -432,43 +429,11 @@ module MessageDriver
432
429
  end
433
430
  end
434
431
 
435
- def initialize_connection
436
- if @handle_connection_errors
437
- if @connection_thread.nil?
438
- #hi mom!
439
- @connection_thread = Thread.new do
440
- @connection = Bunny.new(@config)
441
- begin
442
- sleep
443
- rescue *NETWORK_ERRORS => e
444
- logger.error "error on connection\n#{exception_to_str(e)}"
445
- if @connection.automatically_recover?
446
- sleep 0.1
447
- unless @connection.recovering_from_network_failure?
448
- stop
449
- end
450
- else
451
- stop
452
- end
453
- retry
454
- rescue => e
455
- logger.error "unhandled error in connection thread! #{exception_to_str(e)}"
456
- end
457
- end
458
- @connection_thread.abort_on_exception = true
459
- sleep 0.1
460
- end
461
- sleep 0.1 while @connection_thread.status != 'sleep'
462
- else
463
- @connection ||= Bunny.new(@config)
464
- end
465
- end
466
-
467
432
  def validate_bunny_version
468
- required = Gem::Requirement.create('>= 0.10.8')
433
+ required = Gem::Requirement.create('>= 1.1.3')
469
434
  current = Gem::Version.create(Bunny::VERSION)
470
435
  unless required.satisfied_by? current
471
- raise MessageDriver::Error, "bunny 0.10.8 or later is required for the bunny adapter"
436
+ raise MessageDriver::Error, "bunny 1.1.3 or later is required for the bunny adapter"
472
437
  end
473
438
  end
474
439
  end
@@ -53,7 +53,7 @@ module MessageDriver
53
53
  end
54
54
 
55
55
  def publish(body, headers={}, properties={})
56
- msg = Message.new(body, headers, properties)
56
+ msg = Message.new(nil, body, headers, properties)
57
57
  sub = subscription
58
58
  if sub.nil?
59
59
  message_queue << msg
@@ -68,7 +68,8 @@ module MessageDriver
68
68
  end
69
69
  end
70
70
 
71
- def initialize(config={})
71
+ def initialize(broker, config={})
72
+ @broker = broker
72
73
  @destinations = {}
73
74
  @message_store = Hash.new { |h,k| h[k] = [] }
74
75
  @subscriptions = Hash.new
@@ -13,9 +13,9 @@ module MessageDriver
13
13
 
14
14
  class Message < MessageDriver::Message::Base
15
15
  attr_reader :stomp_message
16
- def initialize(stomp_message)
16
+ def initialize(ctx, stomp_message)
17
17
  @stomp_message = stomp_message
18
- super(stomp_message.body, stomp_message.headers, {})
18
+ super(ctx, stomp_message.body, stomp_message.headers, {})
19
19
  end
20
20
  end
21
21
 
@@ -25,9 +25,10 @@ module MessageDriver
25
25
 
26
26
  attr_reader :config, :poll_timeout
27
27
 
28
- def initialize(config)
28
+ def initialize(broker, config)
29
29
  validate_stomp_version
30
30
 
31
+ @broker = broker
31
32
  @config = config.symbolize_keys
32
33
  connect_headers = @config[:connect_headers] ||= {}
33
34
  connect_headers.symbolize_keys
@@ -52,7 +53,7 @@ module MessageDriver
52
53
  unless name.start_with?("/")
53
54
  name = "/queue/#{name}"
54
55
  end
55
- Destination.new(self, name, dest_options, message_props)
56
+ Destination.new(adapter, name, dest_options, message_props)
56
57
  end
57
58
 
58
59
  def publish(destination, body, headers={}, properties={})
@@ -66,7 +67,6 @@ module MessageDriver
66
67
  sub_id = connection.uuid
67
68
  msg = nil
68
69
  count = 0
69
- options[:id] = sub_id #this is a workaround for https://github.com/stompgem/stomp/issues/56
70
70
  connection.subscribe(destination.name, options, sub_id)
71
71
  while msg.nil? && count < max_poll_count
72
72
  msg = connection.poll
@@ -76,7 +76,7 @@ module MessageDriver
76
76
  end
77
77
  end
78
78
  connection.unsubscribe(destination.name, options, sub_id)
79
- Message.new(msg) if msg
79
+ Message.new(self, msg) if msg
80
80
  end
81
81
  end
82
82
 
@@ -1,40 +1,101 @@
1
- require 'forwardable'
2
- require 'logger'
3
-
4
1
  module MessageDriver
5
2
  class Broker
6
- extend Forwardable
3
+ include Logging
4
+
5
+ DEFAULT_BROKER_NAME = :default
7
6
 
8
- attr_reader :adapter, :configuration, :destinations, :consumers, :logger
7
+ attr_reader :adapter, :configuration, :destinations, :consumers, :name
9
8
 
10
9
  class << self
11
- def configure(options)
12
- @instance = new(options)
10
+ def configure(name = DEFAULT_BROKER_NAME, options)
11
+ if brokers.keys.include? name
12
+ raise BrokerAlreadyConfigured, "there is already a broker named #{name} configured"
13
+ end
14
+ brokers[name] = new(name, options)
15
+ end
16
+
17
+ def define(name = DEFAULT_BROKER_NAME)
18
+ yield broker(name)
19
+ end
20
+
21
+ def broker(name = DEFAULT_BROKER_NAME)
22
+ result = brokers[name]
23
+ if result.nil?
24
+ raise BrokerNotConfigured, "There is no broker named #{name} configured. The configured brokers are #{brokers.keys}"
25
+ end
26
+ result
27
+ end
28
+
29
+ def client(name)
30
+ unless result = clients[name]
31
+ result = clients[name] = Client.for_broker(name)
32
+ end
33
+ result
34
+ end
35
+
36
+ def stop_all
37
+ each_broker do |brk|
38
+ brk.stop
39
+ end
13
40
  end
14
41
 
15
- def method_missing(m, *args, &block)
16
- @instance.send(m, *args, &block)
42
+ def restart_all
43
+ each_broker do |brk|
44
+ brk.restart
45
+ end
17
46
  end
18
47
 
19
- def instance
20
- @instance
48
+ def reset_after_tests
49
+ each_broker do |brk|
50
+ brk.adapter.reset_after_tests
51
+ end
21
52
  end
22
53
 
23
- def define
24
- yield @instance
54
+ def reset
55
+ each_broker do |brk|
56
+ begin
57
+ brk.stop
58
+ rescue => e
59
+ Logging.logger.warn Logging.message_with_exception("error stopping broker #{brk.name}", e)
60
+ end
61
+ end
62
+ brokers.clear
63
+ end
64
+
65
+ private
66
+ def brokers
67
+ @brokers ||= { }
68
+ end
69
+
70
+ def clients
71
+ @clients ||= { }
72
+ end
73
+
74
+ def each_broker
75
+ brokers.keys.each do |k|
76
+ yield brokers[k]
77
+ end
25
78
  end
26
79
  end
27
80
 
28
- def initialize(options)
81
+ def initialize(name = DEFAULT_BROKER_NAME, options)
82
+ @name = name
29
83
  @adapter = resolve_adapter(options[:adapter], options)
30
84
  @stopped = false
31
85
  @configuration = options
32
86
  @destinations = {}
33
87
  @consumers = {}
34
- @logger = options[:logger] || Logger.new(STDOUT).tap{|l| l.level = Logger::INFO}
35
88
  logger.debug "MessageDriver configured successfully!"
36
89
  end
37
90
 
91
+ def logger
92
+ MessageDriver.logger
93
+ end
94
+
95
+ def client
96
+ @client ||= self.class.client(name)
97
+ end
98
+
38
99
  def stop
39
100
  @adapter.stop
40
101
  @stopped = true
@@ -53,11 +114,11 @@ module MessageDriver
53
114
  end
54
115
 
55
116
  def dynamic_destination(dest_name, dest_options={}, message_props={})
56
- Client.dynamic_destination(dest_name, dest_options, message_props)
117
+ client.dynamic_destination(dest_name, dest_options, message_props)
57
118
  end
58
119
 
59
120
  def destination(key, dest_name, dest_options={}, message_props={})
60
- dest = Client.dynamic_destination(dest_name, dest_options, message_props)
121
+ dest = self.dynamic_destination(dest_name, dest_options, message_props)
61
122
  @destinations[key] = dest
62
123
  end
63
124
 
@@ -87,7 +148,7 @@ module MessageDriver
87
148
  when Symbol, String
88
149
  resolve_adapter(find_adapter_class(adapter), options)
89
150
  when Class
90
- resolve_adapter(adapter.new(options), options)
151
+ resolve_adapter(adapter.new(self, options), options)
91
152
  when MessageDriver::Adapters::Base
92
153
  adapter
93
154
  else
@@ -101,7 +162,7 @@ module MessageDriver
101
162
  adapter_method = "#{adapter_name}_adapter"
102
163
 
103
164
  unless respond_to?(adapter_method)
104
- raise "the adapter #{adapter_name} must provide MessageDriver::Broker.#{adapter_method} that returns the adapter class"
165
+ raise "the adapter #{adapter_name} must provide MessageDriver::Broker##{adapter_method} that returns the adapter class"
105
166
  end
106
167
 
107
168
  send(adapter_method)
@@ -30,23 +30,30 @@ module MessageDriver
30
30
  end
31
31
 
32
32
  def ack_message(message, options={})
33
- ctx = current_adapter_context
34
- if ctx.supports_client_acks?
35
- ctx.ack_message(message, options)
36
- else
37
- logger.debug("this adapter does not support client acks")
38
- end
33
+ message.ack(options)
39
34
  end
40
35
 
41
36
  def nack_message(message, options={})
42
- ctx = current_adapter_context
43
- if ctx.supports_client_acks?
44
- ctx.nack_message(message, options)
37
+ message.nack(options)
38
+ end
39
+
40
+ def consumer(key, &block)
41
+ broker.consumer(key, &block)
42
+ end
43
+
44
+ def find_destination(destination)
45
+ case destination
46
+ when Destination::Base
47
+ destination
45
48
  else
46
- logger.debug("this adapter does not support client acks")
49
+ broker.find_destination(destination)
47
50
  end
48
51
  end
49
52
 
53
+ def find_consumer(consumer)
54
+ broker.find_consumer(consumer)
55
+ end
56
+
50
57
  def with_message_transaction(options={}, &block)
51
58
  wrapper = fetch_context_wrapper
52
59
  wrapper.increment_transaction_depth
@@ -83,7 +90,7 @@ module MessageDriver
83
90
  end
84
91
 
85
92
  def with_adapter_context(adapter_context, &block)
86
- old_ctx, Thread.current[:adapter_context] = fetch_context_wrapper(false), build_context_wrapper(adapter_context)
93
+ old_ctx, Thread.current[adapter_context_key] = fetch_context_wrapper(false), build_context_wrapper(adapter_context)
87
94
  begin
88
95
  yield
89
96
  ensure
@@ -99,44 +106,59 @@ module MessageDriver
99
106
  end
100
107
  end
101
108
 
109
+ def broker
110
+ Broker.broker(broker_name)
111
+ end
112
+
113
+ def broker_name
114
+ Broker::DEFAULT_BROKER_NAME
115
+ end
116
+
117
+ def for_broker(_broker_name)
118
+ Module.new do |mod|
119
+ include Client
120
+ extend self
121
+
122
+ define_method :broker_name do
123
+ _broker_name
124
+ end
125
+ end
126
+ end
127
+ module_function :for_broker
128
+
129
+ def [](index)
130
+ Broker.client(index)
131
+ end
132
+
102
133
  private
103
134
 
104
135
  def fetch_context_wrapper(initialize=true)
105
- wrapper = Thread.current[:adapter_context]
136
+ wrapper = Thread.current[adapter_context_key]
106
137
  if wrapper.nil? || !wrapper.valid?
107
138
  if initialize
108
139
  wrapper = build_context_wrapper
109
140
  else
110
141
  wrapper = nil
111
142
  end
112
- Thread.current[:adapter_context] = wrapper
143
+ Thread.current[adapter_context_key] = wrapper
113
144
  end
114
145
  wrapper
115
146
  end
116
147
 
117
148
  def set_context_wrapper(wrapper)
118
- Thread.current[:adapter_context] = wrapper
149
+ Thread.current[adapter_context_key] = wrapper
119
150
  end
120
151
 
121
- def build_context_wrapper(ctx=Broker.adapter.new_context)
152
+ def build_context_wrapper(ctx=adapter.new_context)
122
153
  ContextWrapper.new(ctx)
123
154
  end
124
155
 
125
- def find_destination(destination)
126
- case destination
127
- when Destination::Base
128
- destination
129
- else
130
- Broker.find_destination(destination)
131
- end
132
- end
133
-
134
- def find_consumer(consumer)
135
- Broker.find_consumer(consumer)
156
+ def adapter
157
+ broker.adapter
136
158
  end
137
159
 
138
- def adapter
139
- Broker.adapter
160
+ def adapter_context_key
161
+ @__adapter_context_key ||= "#{broker_name}_adapter_context".to_sym
140
162
  end
141
163
 
142
164
  class ContextWrapper
@@ -161,5 +183,4 @@ module MessageDriver
161
183
  end
162
184
  end
163
185
  end
164
-
165
186
  end
@@ -11,11 +11,11 @@ module MessageDriver
11
11
  end
12
12
 
13
13
  def publish(body, headers={}, properties={})
14
- Client.publish(self, body, headers, properties)
14
+ adapter.broker.client.publish(self, body, headers, properties)
15
15
  end
16
16
 
17
17
  def pop_message(options={})
18
- Client.pop_message(self, options)
18
+ adapter.broker.client.pop_message(self, options)
19
19
  end
20
20
 
21
21
  def after_initialize(adapter_context)
@@ -5,6 +5,8 @@ require 'nesty'
5
5
 
6
6
  module MessageDriver
7
7
  class Error < StandardError; end
8
+ class BrokerNotConfigured < Error; end
9
+ class BrokerAlreadyConfigured < Error; end
8
10
  class TransactionError < Error; end
9
11
  class TransactionRollbackOnly < TransactionError; end
10
12
  class NoSuchDestinationError < Error; end
@@ -1,11 +1,17 @@
1
1
  module MessageDriver
2
2
  module Logging
3
+ extend self
4
+
3
5
  def logger
4
- MessageDriver::Broker.logger
6
+ MessageDriver.logger
5
7
  end
6
8
 
7
9
  def exception_to_str(e)
8
10
  (["#{e.class}: #{e.to_s}"] + e.backtrace).join("\n ")
9
11
  end
12
+
13
+ def message_with_exception(message, e)
14
+ [message, exception_to_str(e)].join("\n")
15
+ end
10
16
  end
11
17
  end
@@ -1,20 +1,31 @@
1
1
  module MessageDriver
2
2
  module Message
3
3
  class Base
4
- attr_reader :body, :headers, :properties
4
+ include Logging
5
5
 
6
- def initialize(body, headers, properties)
6
+ attr_reader :ctx, :body, :headers, :properties
7
+
8
+ def initialize(ctx, body, headers, properties)
9
+ @ctx = ctx
7
10
  @body = body
8
11
  @headers = headers
9
12
  @properties = properties
10
13
  end
11
14
 
12
15
  def ack(options={})
13
- Client.ack_message(self, options)
16
+ if ctx.supports_client_acks?
17
+ ctx.ack_message(self, options)
18
+ else
19
+ logger.debug("this adapter does not support client acks")
20
+ end
14
21
  end
15
22
 
16
23
  def nack(options={})
17
- Client.nack_message(self, options)
24
+ if ctx.supports_client_acks?
25
+ ctx.nack_message(self, options)
26
+ else
27
+ logger.debug("this adapter does not support client acks")
28
+ end
18
29
  end
19
30
  end
20
31
  end
@@ -1,5 +1,5 @@
1
1
  module Message
2
2
  module Driver
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -1,8 +1,9 @@
1
1
  require 'message_driver/version'
2
+ require 'logger'
2
3
 
4
+ require 'message_driver/logging'
3
5
  require 'message_driver/errors'
4
6
  require 'message_driver/broker'
5
- require 'message_driver/logging'
6
7
  require 'message_driver/message'
7
8
  require 'message_driver/destination'
8
9
  require 'message_driver/subscription'
@@ -10,11 +11,17 @@ require 'message_driver/adapters/base'
10
11
  require 'message_driver/client'
11
12
 
12
13
  module MessageDriver
13
- def self.configure(options={})
14
- Broker.configure(options)
14
+ module_function
15
+ def configure(broker_name = Broker::DEFAULT_BROKER_NAME, options)
16
+ Broker.configure(broker_name, options)
15
17
  end
16
18
 
17
- def self.stop
18
- Broker.stop
19
+ def logger
20
+ @__logger ||= Logger.new(STDOUT).tap{|l| l.level = Logger::INFO}
19
21
  end
22
+
23
+ def logger=(logger)
24
+ @__logger = logger
25
+ end
26
+
20
27
  end