announce 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9789a278d07101dcd8a592549cd616a0d9792577
4
- data.tar.gz: 9bdb61307e9b940ba340bd604a42acee381f0f26
3
+ metadata.gz: c4197e2523a8f2fde2b5c27b19d7ffff59864c21
4
+ data.tar.gz: 447f8331968cedbaa1c11d7e412f1a9d49eaf9f2
5
5
  SHA512:
6
- metadata.gz: 0422db42eed7b943f3fde2133ad9e6b67438eab02b874697d4b39b5cb54b65bda5470e5b262241dfeec49332a2db3d71d137915f78d54cbf44da88a9229130ef
7
- data.tar.gz: 0689cc11bb610d00bbd074bf41924d589a3be572b75f167f1e2a1817b363b8bdcf3298cbfd772847b3b0a8aa328418938ef861e83373b283eaf1a01c211b0c03
6
+ metadata.gz: f96f65e1562900251b14ba50068ec9a2926202250deb371c42be86de5f33fc2e792d071a4c7ae0080286c9a44501646f2c096ae164104d3f14c87a2562908ee5
7
+ data.tar.gz: 3408e11b3d4aa7009532040d42bce7a2f9330771b63412559eea0b04cdd779bd357b572b0004e1d858019b5aa5694729706c30109a1230f9e53a251a2d015336
data/.travis.yml CHANGED
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.2
4
- - 2.2.1
3
+ - 2.1.10
4
+ - 2.2.5
5
+ - 2.3.1
5
6
  env:
6
7
  global:
7
8
  - TRAVIS=true
data/README.md CHANGED
@@ -32,7 +32,7 @@ end
32
32
  ```
33
33
 
34
34
  When building a Ruby app or service to receive messages, subscribe a job class to announcements like this:
35
- ```
35
+ ```ruby
36
36
  require 'announce'
37
37
 
38
38
  class SomeCreateJob < ActiveJob::Base
@@ -223,7 +223,7 @@ Announce.announce(:story, :publish, id: story.id, {})
223
223
  ```
224
224
 
225
225
  There is also a module you can include to get `publish` and `announce` methods:
226
- ```
226
+ ```ruby
227
227
  class SomeController
228
228
  include Announce::Publisher
229
229
 
@@ -247,7 +247,7 @@ Unlike other job libraries which specify the Ruby `Class` for processing as part
247
247
 
248
248
  To designate that a Ruby class will process a message, you must include the `Announce:Subscriber` module and call `subscribe_to` class method.
249
249
 
250
- ```
250
+ ```ruby
251
251
  require 'announce'
252
252
 
253
253
  class SomeCreateJob < ActiveJob::Base
@@ -264,7 +264,7 @@ end
264
264
  This works because the `Announce::Subscriber` adds the `subscribe_to` class method, but also a default `perform(*args)` instance method that delegates message handling to a job instance method named `"receive_#{subject}_#{action}"`.
265
265
 
266
266
  This default `perform` method only passes the message `body` to `receive_subject_action` methods. The `subject`, but `action` and full `message` object are made available as instance properties of the subscriber.
267
- ```
267
+ ```ruby
268
268
  require 'announce'
269
269
 
270
270
  class SomeCreateJob < ActiveJob::Base
@@ -302,6 +302,42 @@ For `shoryuken`, `subscribe_to` registers the worker for the appropriate queue,
302
302
 
303
303
  ## Development
304
304
 
305
+ ### Testing with Announce
306
+
307
+ There is an Announce::Testing module which provides helper methods useful in your tests.
308
+ To use them add the following lines into your test/spec helper:
309
+ ```ruby
310
+ # use the testing helper
311
+ require 'announce/testing'
312
+
313
+ # include the methods - could also include in your base test class
314
+ include Announce::Testing
315
+
316
+ # this resets announce to use test settings, and clears messages
317
+ reset_announce
318
+
319
+ ```
320
+
321
+ Then you can use the following methods in your test class:
322
+
323
+ `published_messages` - returns the array of published messages
324
+
325
+ `last_message` - returns the last message published to announce
326
+
327
+ `clear_messages` - clears all published messages
328
+
329
+ `subscriptions` - returns the array of all subscriptions
330
+
331
+ `last_subscription` - returns most recently added subscription
332
+
333
+ `clear_subscriptions` - clears all subscriptions
334
+
335
+ `broker_configured?` - returns whether or not the broker has been configured
336
+
337
+ `reset_broker_config` - resets broker
338
+
339
+ `reset_announce` - resets announce to use test adapter, prefix, app, and logging to `/dev/null`
340
+
305
341
  ### Developing an Adapter Class
306
342
 
307
343
  Adapter classes should be named with the following module structure: `Announce::Adapters::SomeBrokerAdapter`
data/announce.gemspec CHANGED
@@ -19,12 +19,13 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency 'shoryuken', '~> 1.0'
22
+ spec.add_development_dependency 'shoryuken', '~> 2.0.5'
23
23
  spec.add_development_dependency 'bundler'
24
24
  spec.add_development_dependency 'rake'
25
25
  spec.add_development_dependency 'growl'
26
26
  spec.add_development_dependency 'minitest'
27
27
  spec.add_development_dependency 'guard'
28
+ spec.add_development_dependency 'listen', '~> 3.2.0'
28
29
  spec.add_development_dependency 'guard-minitest'
29
30
  spec.add_development_dependency 'dotenv'
30
31
  spec.add_development_dependency 'simplecov'
@@ -1,33 +1,37 @@
1
- require 'announce'
2
- require 'announce/message'
1
+ require "announce"
2
+ require "announce/message"
3
3
 
4
- # publish, subscribe, and configure_broker are the 3 required methods for an adapter
5
- # this base adapter also has some helpful base classes, but they are not necessary
6
- # you could write an adapter from scratch so long as the class has these 3 class methods.
4
+ # publish, subscribe, & configure_broker are the 3 required methods for adapters
5
+ # the base adapter also has helpful base classes, but they are not necessary
6
+ # you can write an adapter from scratch, but these 3 class methods are required.
7
7
  module Announce
8
8
  module Adapters
9
9
  class BaseAdapter
10
-
11
10
  class << self
12
-
11
+ # required
13
12
  def publish(subject, action, body, options = {})
14
13
  topic = adapter_constantize(:topic).new(subject, action, options)
15
- msg = Announce::Message.new(subject: subject, action: action, body: body)
14
+ msg =
15
+ Announce::Message.new(subject: subject, action: action, body: body)
16
16
  topic.publish(msg.to_message, options)
17
17
  end
18
18
 
19
+ # required
19
20
  def subscribe(worker_class, subject, actions = [], options = {})
20
21
  subscriber = adapter_constantize(:subscriber).new
21
22
  subscriber.subscribe(worker_class, subject, actions, options)
22
23
  end
23
24
 
25
+ # required
24
26
  def configure_broker(options)
25
27
  broker_manager = adapter_constantize(:broker_manager).new(options)
26
28
  broker_manager.configure
27
29
  end
28
30
 
29
31
  def adapter_constantize(name)
30
- "::Announce::Adapters::#{Announce.options[:adapter].to_s.camelize}Adapter::#{name.to_s.camelize}".constantize
32
+ a_klass = Announce.options[:adapter].to_s.camelize
33
+ klass = name.to_s.camelize
34
+ "::Announce::Adapters::#{a_klass}Adapter::#{klass}".constantize
31
35
  end
32
36
  end
33
37
 
@@ -41,8 +45,8 @@ module Announce
41
45
  attr_accessor :options
42
46
 
43
47
  # uses the configuration
44
- def initialize(options = Announce.options)
45
- @options = options
48
+ def initialize(options = {})
49
+ @options = Announce.options.merge(options)
46
50
  end
47
51
 
48
52
  # actually configure the broker queues, topics, and subscriptions
@@ -62,6 +66,10 @@ module Announce
62
66
  raise NotImplementedError.new("You must implement create.")
63
67
  end
64
68
 
69
+ def verify
70
+ raise NotImplementedError.new("You must implement verify.")
71
+ end
72
+
65
73
  def self.name_for(subject, action)
66
74
  [prefix, namespace, subject, action].join(delimiter)
67
75
  end
@@ -93,8 +101,7 @@ module Announce
93
101
  end
94
102
  end
95
103
 
96
- class Topic < Destination
97
- end
104
+ class Topic < Destination; end
98
105
 
99
106
  class Queue < Destination
100
107
  def self.name_for(subject, action)
@@ -1,9 +1,8 @@
1
- require 'announce/adapters/base_adapter'
1
+ require "announce/adapters/base_adapter"
2
2
 
3
3
  module Announce
4
4
  module Adapters
5
5
  class InlineAdapter < BaseAdapter
6
-
7
6
  def self.subscriptions
8
7
  @@subscriptions ||= {}
9
8
  end
@@ -34,8 +33,7 @@ module Announce
34
33
  end
35
34
  end
36
35
 
37
- class Queue < BaseAdapter::Queue
38
- end
36
+ class Queue < BaseAdapter::Queue; end
39
37
  end
40
38
  end
41
39
  end
@@ -1,27 +1,24 @@
1
- require 'shoryuken'
2
- require 'announce/adapters/base_adapter'
1
+ require "shoryuken"
2
+ require "announce/adapters/base_adapter"
3
3
 
4
4
  module Announce
5
5
  module Adapters
6
6
  class ShoryukenAdapter < BaseAdapter
7
-
8
7
  class AnnounceWorker #:nodoc:
9
8
  include Shoryuken::Worker
10
9
 
11
10
  shoryuken_options body_parser: :json, auto_delete: true
12
11
 
13
12
  # overriden in register_class
14
- def job_class
15
- end
13
+ def job_class; end
16
14
 
17
15
  def perform(sqs_msg, hash)
18
16
  job = job_class.new(hash)
19
- Base.execute(job.serialize)
17
+ ActiveJob::Base.execute(job.serialize)
20
18
  end
21
19
  end
22
20
 
23
21
  class Subscriber < BaseAdapter::Subscriber
24
-
25
22
  def subscribe(worker_class, subject, actions, options)
26
23
  Array(actions).each do |action|
27
24
  queue_name = Queue.name_for(subject, action)
@@ -42,22 +39,31 @@ module Announce
42
39
 
43
40
  def active_job?
44
41
  defined?(::ActiveJob) &&
45
- defined?(ActiveJob::QueueAdapters::ShoryukenAdapter) &&
46
- ActiveJob::Base.queue_adapter == ActiveJob::QueueAdapters::ShoryukenAdapter
42
+ defined?(ActiveJob::QueueAdapters::ShoryukenAdapter) &&
43
+ ActiveJob::Base.queue_adapter ==
44
+ ActiveJob::QueueAdapters::ShoryukenAdapter
47
45
  end
48
46
  end
49
47
 
50
48
  class BrokerManager < BaseAdapter::BrokerManager
51
-
52
49
  # actually configure the broker queues, topics, and subscriptions
53
50
  def configure
51
+ if options[:verify_only]
52
+ Announce.logger.warn(
53
+ "Running Announce BrokerManager configure in verify_only mode."
54
+ )
55
+ Announce.logger.warn(
56
+ "Resources will be logged, not created; please verify they exist."
57
+ )
58
+ end
54
59
  configure_publishing && configure_subscribing
55
60
  end
56
61
 
57
62
  def configure_publishing
58
63
  (options[:publish] || {}).each do |subject, actions|
59
64
  Array(actions).each do |action|
60
- ShoryukenAdapter::Topic.new(subject, action, options).create
65
+ topic = ShoryukenAdapter::Topic.new(subject, action, options)
66
+ options[:verify_only] ? topic.verify : topic.create
61
67
  end
62
68
  end
63
69
  true
@@ -68,9 +74,15 @@ module Announce
68
74
  Array(actions).each do |action|
69
75
  topic = ShoryukenAdapter::Topic.new(subject, action, options)
70
76
  queue = ShoryukenAdapter::Queue.new(subject, action, options)
71
- topic.create
72
- queue.create
73
- topic.subscribe(queue)
77
+ if options[:verify_only]
78
+ topic.verify
79
+ queue.verify
80
+ topic.verify_subscription(queue)
81
+ else
82
+ topic.create
83
+ queue.create
84
+ topic.subscribe(queue)
85
+ end
74
86
  end
75
87
  end
76
88
  true
@@ -78,7 +90,6 @@ module Announce
78
90
  end
79
91
 
80
92
  class Topic < BaseAdapter::Topic
81
-
82
93
  def publish(message, options = {})
83
94
  Shoryuken::Client.topics(name).send_message(message, options)
84
95
  end
@@ -87,17 +98,28 @@ module Announce
87
98
  sns.create_topic(name: name)[:topic_arn]
88
99
  end
89
100
 
101
+ def verify
102
+ Announce.logger.warn("Verify SNS Topic: #{arn}")
103
+ end
104
+
105
+ def verify_subscription(queue)
106
+ Announce.logger.warn(
107
+ "Verify Subscription:\n"\
108
+ " from SNS Topic: #{arn}\n"\
109
+ " to SQS Queue: #{queue.arn}"
110
+ )
111
+ end
112
+
90
113
  def subscribe(queue)
91
- subscription_arn = sns.subscribe(
92
- topic_arn: arn,
93
- protocol: 'sqs',
94
- endpoint: queue.arn
95
- )[:subscription_arn]
114
+ subscription_arn =
115
+ sns.subscribe(topic_arn: arn, protocol: "sqs", endpoint: queue.arn)[
116
+ :subscription_arn
117
+ ]
96
118
 
97
119
  sns.set_subscription_attributes(
98
120
  subscription_arn: subscription_arn,
99
- attribute_name: 'RawMessageDelivery',
100
- attribute_value: 'true'
121
+ attribute_name: "RawMessageDelivery",
122
+ attribute_value: "true"
101
123
  )
102
124
  subscription_arn
103
125
  end
@@ -114,14 +136,25 @@ module Announce
114
136
  end
115
137
 
116
138
  class Queue < BaseAdapter::Queue
139
+ DLQ_SUFFIX = "failures".freeze
117
140
 
118
141
  def create
119
- create_attributes = default_options.merge((options[:queues] || {}).stringify_keys)
120
-
121
142
  dlq_arn = create_dlq
122
- create_attributes['RedrivePolicy'] = %Q{{"maxReceiveCount":"10", "deadLetterTargetArn":"#{dlq_arn}"}"}
123
143
 
124
- sqs.create_queue(queue_name: name, attributes: create_attributes)[:queue_url]
144
+ create_attributes =
145
+ default_options.merge((options[:queues] || {}).stringify_keys)
146
+ create_attributes["RedrivePolicy"] =
147
+ '{"maxReceiveCount":"10", "deadLetterTargetArn":"' + dlq_arn + '"}'
148
+
149
+ sqs.create_queue(queue_name: name, attributes: create_attributes)[
150
+ :queue_url
151
+ ]
152
+ end
153
+
154
+ def verify
155
+ Announce.logger.warn(
156
+ "Verify SQS Queue: #{arn}\n\t with DLQ: #{dlq_arn}"
157
+ )
125
158
  end
126
159
 
127
160
  def arn
@@ -131,34 +164,40 @@ module Announce
131
164
  end
132
165
 
133
166
  def create_dlq
134
- dlq_name = "#{name}_failures"
135
-
136
167
  dlq_options = {
137
- 'MaximumMessageSize' => "#{(256 * 1024)}",
138
- 'MessageRetentionPeriod' => "#{2 * 7 * 24 * 60 * 60}" # 2 weeks in seconds
168
+ "MaximumMessageSize" => (256 * 1024).to_s,
169
+ "MessageRetentionPeriod" => (2 * 7 * 24 * 60 * 60).to_s
170
+ # 2 weeks in seconds
139
171
  }
140
172
 
141
- dlq = sqs.create_queue(
142
- queue_name: dlq_name,
143
- attributes: dlq_options
144
- )
173
+ dlq = sqs.create_queue(queue_name: dlq_name, attributes: dlq_options)
145
174
 
146
- attrs = sqs.get_queue_attributes(
147
- queue_url: dlq[:queue_url],
148
- attribute_names: ['QueueArn']
149
- )
175
+ attrs =
176
+ sqs.get_queue_attributes(
177
+ queue_url: dlq[:queue_url], attribute_names: %w[QueueArn]
178
+ )
179
+
180
+ attrs.attributes["QueueArn"]
181
+ end
150
182
 
151
- attrs.attributes['QueueArn']
183
+ def dlq_arn
184
+ [arn, DLQ_SUFFIX].join(self.class.delimiter)
185
+ end
186
+
187
+ def dlq_name
188
+ [name, DLQ_SUFFIX].join(self.class.delimiter)
152
189
  end
153
190
 
154
191
  def default_options
155
192
  {
156
- 'DelaySeconds' => '0',
157
- 'MaximumMessageSize' => "#{256 * 1024}",
158
- 'VisibilityTimeout' => "#{60 * 60}", # 1 hour in seconds
159
- 'ReceiveMessageWaitTimeSeconds' => '0',
160
- 'MessageRetentionPeriod' => "#{7 * 24 * 60 * 60}", # 1 week in seconds
161
- 'Policy' => policy
193
+ "DelaySeconds" => "0",
194
+ "MaximumMessageSize" => (256 * 1024).to_s,
195
+ "VisibilityTimeout" => (60 * 60).to_s,
196
+ # 1 hour in seconds
197
+ "ReceiveMessageWaitTimeSeconds" => "0",
198
+ "MessageRetentionPeriod" => (7 * 24 * 60 * 60).to_s,
199
+ # 1 week in seconds
200
+ "Policy" => policy
162
201
  }
163
202
  end
164
203
 
@@ -172,9 +211,7 @@ module Announce
172
211
  {
173
212
  "Sid" => "1",
174
213
  "Effect" => "Allow",
175
- "Principal" => {
176
- "AWS" => "*"
177
- },
214
+ "Principal" => { "AWS" => "*" },
178
215
  "Action" => "sqs:*",
179
216
  "Resource" => arn,
180
217
  "Condition" => {
@@ -195,4 +232,6 @@ module Announce
195
232
  end
196
233
  end
197
234
 
198
- Shoryuken::Client.account_id = ENV['AWS_ACCOUNT_ID'] unless Shoryuken::Client.account_id
235
+ unless Shoryuken::Client.account_id
236
+ Shoryuken::Client.account_id = ENV["AWS_ACCOUNT_ID"]
237
+ end
@@ -1,11 +1,9 @@
1
- require 'announce/adapters/base_adapter'
1
+ require "announce/adapters/base_adapter"
2
2
 
3
3
  module Announce
4
4
  module Adapters
5
5
  class TestAdapter < BaseAdapter
6
-
7
6
  class Subscriber < BaseAdapter::Subscriber
8
-
9
7
  @@subscriptions = []
10
8
 
11
9
  def self.subscriptions
@@ -35,7 +33,6 @@ module Announce
35
33
  end
36
34
 
37
35
  class Topic < BaseAdapter::Topic
38
-
39
36
  @@published_messages = []
40
37
 
41
38
  def self.published_messages
@@ -50,12 +47,22 @@ module Announce
50
47
  def create
51
48
  true
52
49
  end
50
+
51
+ def verify
52
+ Announce.logger.debug("#{self.class.name}: verify #{name}")
53
+ true
54
+ end
53
55
  end
54
56
 
55
57
  class Queue < BaseAdapter::Queue
56
58
  def create
57
59
  true
58
60
  end
61
+
62
+ def verify
63
+ Announce.logger.debug("#{self.class.name}: verify #{name}")
64
+ true
65
+ end
59
66
  end
60
67
  end
61
68
  end
@@ -1,5 +1,5 @@
1
- require 'yaml'
2
- require 'erb'
1
+ require "yaml"
2
+ require "erb"
3
3
 
4
4
  module Announce
5
5
  class Configuration
@@ -14,16 +14,18 @@ module Announce
14
14
  {}.tap do |defaults|
15
15
  if defined?(ActiveJob)
16
16
  defaults[:queue_name_prefix] = ::ActiveJob::Base.queue_name_prefix
17
- defaults[:queue_name_delimiter] = ::ActiveJob::Base.queue_name_delimiter
17
+ defaults[:queue_name_delimiter] =
18
+ ::ActiveJob::Base.queue_name_delimiter
18
19
  defaults[:adapter] = aj_queue_adapter_name
19
20
  else
20
- defaults[:queue_name_prefix] = ENV['RAILS_ENV'] || ENV['APP_ENV'] || 'development'
21
- defaults[:queue_name_delimiter] = '_'
21
+ defaults[:queue_name_prefix] =
22
+ ENV["RAILS_ENV"] || ENV["APP_ENV"] || "development"
23
+ defaults[:queue_name_delimiter] = "_"
22
24
  defaults[:adapter] = :inline
23
25
  end
24
26
 
25
- defaults[:app_name] = 'app'
26
- defaults[:namespace] = 'announce'
27
+ defaults[:app_name] = "app"
28
+ defaults[:namespace] = "announce"
27
29
  end
28
30
  end
29
31
 
@@ -35,7 +37,7 @@ module Announce
35
37
  def initialize(options)
36
38
  @options = options
37
39
  base = defined?(Rails) ? Rails.root : Dir.pwd
38
- options[:config_file] ||= File.join(base, 'config', 'announce.yml')
40
+ options[:config_file] ||= File.join(base, "config", "announce.yml")
39
41
  end
40
42
 
41
43
  def config_file
@@ -45,7 +47,9 @@ module Announce
45
47
  def configure
46
48
  defaults = self.class.default_options
47
49
  if File.exist?(config_file)
48
- defaults.merge(YAML.load(ERB.new(IO.read(config_file)).result).symbolize_keys)
50
+ defaults.merge(
51
+ YAML.safe_load(ERB.new(IO.read(config_file)).result).symbolize_keys
52
+ )
49
53
  else
50
54
  Announce.logger.warn "PubSub file #{config_file} does not exist"
51
55
  defaults
@@ -1,7 +1,7 @@
1
1
  begin
2
- require 'active_support/core_ext/hash/keys'
3
- require 'active_support/core_ext/hash/deep_merge'
4
- require 'active_support/core_ext/hash/slice'
2
+ require "active_support/core_ext/hash/keys"
3
+ require "active_support/core_ext/hash/deep_merge"
4
+ require "active_support/core_ext/hash/slice"
5
5
  rescue LoadError
6
6
  class Hash
7
7
  def stringify_keys
@@ -36,11 +36,11 @@ rescue LoadError
36
36
  end
37
37
 
38
38
  begin
39
- require 'active_support/core_ext/string/inflections'
39
+ require "active_support/core_ext/string/inflections"
40
40
  rescue LoadError
41
41
  class String
42
42
  def constantize
43
- names = self.split('::')
43
+ names = self.split("::")
44
44
  names.shift if names.empty? || names.first.empty?
45
45
 
46
46
  constant = Object
@@ -54,14 +54,14 @@ rescue LoadError
54
54
  string = self
55
55
  string = string.sub(/^[a-z\d]*/) { $&.capitalize }
56
56
  string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
57
- string.gsub!(/\//, '::')
57
+ string.gsub!(/\//, "::")
58
58
  string
59
59
  end
60
60
 
61
61
  def underscore
62
62
  camel_cased_word = self
63
63
  return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
64
- word = camel_cased_word.to_s.gsub(/::/, '/')
64
+ word = camel_cased_word.to_s.gsub(/::/, "/")
65
65
  word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
66
66
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
67
67
  word.tr!("-", "_")
@@ -1,16 +1,17 @@
1
- require 'json'
1
+ require "securerandom"
2
+ require "json"
2
3
 
3
4
  module Announce
4
5
  class Message
5
-
6
6
  attr_accessor :options
7
7
 
8
- def initialize(options={})
9
- @options = {
10
- 'message_id' => SecureRandom.uuid,
11
- 'app' => app,
12
- 'sent_at' => Time.now.utc
13
- }.merge(options).stringify_keys
8
+ def initialize(options = {})
9
+ @options =
10
+ {
11
+ "message_id" => ::SecureRandom.uuid,
12
+ "app" => app,
13
+ "sent_at" => Time.now.utc
14
+ }.merge(options).stringify_keys
14
15
  end
15
16
 
16
17
  def app
@@ -1,6 +1,5 @@
1
- require 'shoryuken'
2
- require 'announce'
3
- require 'announce/message'
1
+ require "shoryuken"
2
+ require "announce/message"
4
3
 
5
4
  module Announce
6
5
  module Publisher
@@ -1,8 +1,5 @@
1
1
  module Announce
2
2
  class Railtie < Rails::Railtie
3
-
4
- rake_tasks do
5
- load "tasks/announce.rake"
6
- end
3
+ rake_tasks { load "tasks/announce.rake" }
7
4
  end
8
- end
5
+ end
@@ -1,16 +1,13 @@
1
1
  module Announce
2
2
  module Subscriber
3
-
4
3
  def self.included(base)
5
- base.class_eval do
6
- attr_accessor :subject, :action, :message
7
- end
4
+ base.class_eval { attr_accessor :subject, :action, :message }
8
5
 
9
6
  base.extend(ClassMethods)
10
7
  end
11
8
 
12
9
  module ClassMethods
13
- def subscribe_to(subject, actions=[], options = {})
10
+ def subscribe_to(subject, actions = [], options = {})
14
11
  Announce.subscribe(self, subject, actions, options)
15
12
  end
16
13
  end
@@ -25,19 +22,20 @@ module Announce
25
22
  @subject = message[:subject]
26
23
  @action = message[:action]
27
24
 
28
- if [message, subject, action].any? { |a| a.nil? }
29
- raise "Message, subject, and action are not all specified for '#{event.inspect}'"
25
+ if [message, subject, action].any?(&:nil?)
26
+ raise "Missing message, subject, or action for '#{event.inspect}'"
30
27
  end
31
28
 
32
29
  if respond_to?(delegate_method)
33
30
  public_send(delegate_method, message[:body])
34
31
  else
35
- raise "`#{self.class.name}` is subscribed, but doesn't implement `#{delegate_method}` for '#{event.inspect}'"
32
+ raise "`#{self.class.name}` subscribed, but doesn't implement " \
33
+ "`#{delegate_method}` for '#{event.inspect}'"
36
34
  end
37
35
  end
38
36
 
39
37
  def delegate_method(message = @message)
40
- ['receive', message[:subject], message[:action]].join('_')
38
+ ["receive", message[:subject], message[:action]].join("_")
41
39
  end
42
40
  end
43
41
  end
@@ -0,0 +1,45 @@
1
+ require 'announce/adapters/test_adapter'
2
+
3
+ module Announce
4
+ module Testing
5
+ def published_messages
6
+ Announce::Adapters::TestAdapter::Topic.published_messages
7
+ end
8
+
9
+ def last_message
10
+ published_messages.last
11
+ end
12
+
13
+ def clear_messages
14
+ published_messages.clear
15
+ end
16
+
17
+ def subscriptions
18
+ Announce::Adapters::TestAdapter::Subscriber.subscriptions
19
+ end
20
+
21
+ def last_subscription
22
+ subscriptions.last
23
+ end
24
+
25
+ def clear_subscriptions
26
+ subscriptions.clear
27
+ end
28
+
29
+ def broker_configured?
30
+ Announce::Adapters::TestAdapter::BrokerManager.configured?
31
+ end
32
+
33
+ def reset_broker_config
34
+ Announce::Adapters::TestAdapter::BrokerManager.reset
35
+ end
36
+
37
+ def reset_announce
38
+ Announce.logger = Logger.new('/dev/null')
39
+ Announce.options[:adapter] = 'test'
40
+ Announce.options[:queue_name_prefix] = 'test'
41
+ Announce.options[:app_name] = 'app'
42
+ clear_messages
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module Announce
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/announce.rb CHANGED
@@ -1,17 +1,16 @@
1
- require 'logger'
1
+ require "logger"
2
2
 
3
- require 'announce/configuration'
4
- require 'announce/core_ext'
5
- require 'announce/message'
6
- require 'announce/publisher'
7
- require 'announce/subscriber'
8
- require 'announce/version'
9
- require 'announce/railtie' if defined?(Rails)
3
+ require "announce/configuration"
4
+ require "announce/core_ext"
5
+ require "announce/message"
6
+ require "announce/publisher"
7
+ require "announce/subscriber"
8
+ require "announce/version"
9
+ require "announce/railtie" if defined?(Rails)
10
10
 
11
11
  module Announce
12
12
  class << self
13
-
14
- def publish(subject, action, message, options={})
13
+ def publish(subject, action, message, options = {})
15
14
  adapter_class.publish(subject, action, message, options)
16
15
  end
17
16
 
@@ -21,8 +20,8 @@ module Announce
21
20
  adapter_class.subscribe(worker_class, subject, actions, options)
22
21
  end
23
22
 
24
- def configure_broker
25
- adapter_class.configure_broker(options)
23
+ def configure_broker(opts = {})
24
+ adapter_class.configure_broker(options.merge(opts))
26
25
  end
27
26
 
28
27
  def options
@@ -37,15 +36,12 @@ module Announce
37
36
  def adapter_class
38
37
  announce_adapter = Announce.options[:adapter]
39
38
  require "announce/adapters/#{announce_adapter.to_s.downcase}_adapter"
40
- "::Announce::Adapters::#{announce_adapter.to_s.camelize}Adapter".constantize
39
+ "::Announce::Adapters::#{announce_adapter.to_s.camelize}Adapter"
40
+ .constantize
41
41
  end
42
42
 
43
43
  def logger
44
- @logger ||= if defined?(Rails)
45
- Rails.logger
46
- else
47
- Logger.new(STDOUT)
48
- end
44
+ @logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
49
45
  end
50
46
 
51
47
  def logger=(l)
@@ -1,8 +1,13 @@
1
1
  namespace :announce do
2
2
 
3
3
  desc 'Configure the broker destinations'
4
- task :configure_broker => [:environment] do |t, args|
4
+ task configure_broker: [:environment] do
5
5
  Announce.configure
6
6
  Announce.configure_broker
7
7
  end
8
+
9
+ task verify_config: [:environment] do
10
+ Announce.configure
11
+ Announce.configure_broker(verify_only: true)
12
+ end
8
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: announce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kuklewicz
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-05-15 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: shoryuken
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: 2.0.5
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: 2.0.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: listen
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.2.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.2.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: guard-minitest
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -181,13 +195,14 @@ files:
181
195
  - lib/announce/publisher.rb
182
196
  - lib/announce/railtie.rb
183
197
  - lib/announce/subscriber.rb
198
+ - lib/announce/testing.rb
184
199
  - lib/announce/version.rb
185
200
  - lib/tasks/announce.rake
186
201
  homepage: https://github.com/PRX/announce
187
202
  licenses:
188
203
  - MIT
189
204
  metadata: {}
190
- post_install_message:
205
+ post_install_message:
191
206
  rdoc_options: []
192
207
  require_paths:
193
208
  - lib
@@ -202,9 +217,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
217
  - !ruby/object:Gem::Version
203
218
  version: '0'
204
219
  requirements: []
205
- rubyforge_project:
206
- rubygems_version: 2.2.3
207
- signing_key:
220
+ rubyforge_project:
221
+ rubygems_version: 2.5.1
222
+ signing_key:
208
223
  specification_version: 4
209
224
  summary: Announce is for pubsub of messages
210
225
  test_files: []