propono 0.0.1 → 0.1.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.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *.swp
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script:
5
+ - rake test
6
+ addons:
7
+ code_climate:
8
+ repo_token: 88dd239bc2e0010742a42a4e0234b4decd19b46d0e9d3408d8b1fe0f96dd8fc1
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in propono.gemspec
4
4
  gemspec
5
+
6
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/README.md CHANGED
@@ -3,8 +3,6 @@
3
3
  [![Build Status](https://travis-ci.org/meducation/propono.png)](https://travis-ci.org/meducation/propono)
4
4
  [![Dependencies](https://gemnasium.com/meducation/propono.png?travis)](https://gemnasium.com/meducation/propono)
5
5
  [![Code Climate](https://codeclimate.com/github/meducation/propono.png)](https://codeclimate.com/github/meducation/propono)
6
- [![Coverage Status](https://coveralls.io/repos/meducation/propono/badge.png)](https://coveralls.io/r/meducation/propono)
7
-
8
6
 
9
7
  ## Installation
10
8
 
@@ -20,6 +18,34 @@ And then execute:
20
18
 
21
19
  $ bundle
22
20
 
21
+ This script demonstrates usage:
22
+
23
+ ```ruby
24
+ require 'propono'
25
+
26
+ class Toy
27
+ def play
28
+ configure
29
+ make_fun_stuff_happen
30
+ end
31
+
32
+ private
33
+ def make_fun_stuff_happen
34
+ Propono.publish("jez-test-topic", "A test message")
35
+ Propono.subscribe_by_queue("jez-test-topic")
36
+ Propono.subscribe_by_post("jez-test-topic", 'http://example.com/endpoint')
37
+ end
38
+
39
+ def configure
40
+ Propono.config.access_key = '...'
41
+ Propono.config.secret_key = '...'
42
+ Propono.config.queue_region = 'eu-west-1'
43
+ end
44
+ end
45
+
46
+ Toy.new.play
47
+ ```
48
+
23
49
  ## Contributing
24
50
 
25
51
  Firstly, thank you!! :heart::sparkling_heart::heart:
data/lib/propono.rb CHANGED
@@ -1,11 +1,30 @@
1
1
  require "propono/version"
2
2
  require 'propono/configuration'
3
3
  require 'propono/sns'
4
+ require 'propono/sqs'
5
+ require "propono/post_subscriber"
4
6
  require "propono/publisher"
7
+ require "propono/queue"
8
+ require "propono/queue_creator"
9
+ require "propono/queue_subscriber"
10
+ require "propono/subscriber"
5
11
  require "propono/topic_creator"
6
12
 
7
13
  module Propono
8
- def config
14
+ def self.config
9
15
  Configuration.instance
10
16
  end
17
+
18
+ def self.publish(*args)
19
+ Publisher.publish(*args)
20
+ end
21
+
22
+ def self.subscribe_by_queue(*args)
23
+ Subscriber.subscribe_by_queue(*args)
24
+ end
25
+
26
+ def self.subscribe_by_post(*args)
27
+ Subscriber.subscribe_by_post(*args)
28
+ end
29
+
11
30
  end
@@ -0,0 +1,19 @@
1
+ module Propono
2
+ class PostSubscriber
3
+ include Sns
4
+
5
+ def self.subscribe(topic, endpoint)
6
+ new(topic, endpoint).subscribe
7
+ end
8
+
9
+ def initialize(topic_id, endpoint)
10
+ @topic_id = topic_id
11
+ @endpoint = endpoint
12
+ end
13
+
14
+ def subscribe
15
+ topic_arn = TopicCreator.find_or_create(@topic_id)
16
+ sns.subscribe(topic_arn, @endpoint, 'http')
17
+ end
18
+ end
19
+ end
@@ -9,14 +9,12 @@ module Propono
9
9
  new.publish(topic, message)
10
10
  end
11
11
 
12
- def initialize
13
- end
14
-
15
12
  def publish(topic_id, message)
16
13
  raise PublisherError.new("Topic is nil") if topic_id.nil?
17
14
  raise PublisherError.new("Message is nil") if message.nil?
18
15
 
19
16
  topic_arn = TopicCreator.find_or_create(topic_id)
17
+ sns.publish(topic_arn, message)
20
18
  end
21
19
  end
22
20
  end
@@ -0,0 +1,16 @@
1
+ module Propono
2
+ class Queue
3
+
4
+ include Sqs
5
+
6
+ attr_reader :url
7
+ def initialize(url)
8
+ @url = url
9
+ end
10
+
11
+ def arn
12
+ attributes = sqs.get_queue_attributes(@url, 'QueueArn').body["Attributes"]
13
+ attributes["QueueArn"]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module Propono
2
+ class QueueCreatorError < Exception
3
+ end
4
+
5
+ class QueueCreator
6
+ include Sqs
7
+
8
+ def self.find_or_create(name)
9
+ new(name).find_or_create
10
+ end
11
+
12
+ def initialize(name)
13
+ @name = name
14
+ end
15
+
16
+ def find_or_create
17
+ result = sqs.create_queue(@name)
18
+ body = result.body
19
+ url = body.fetch('QueueUrl') { raise QueueCreatorError.new("No QueueUrl returned from SQS") }
20
+ Queue.new(url)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ module Propono
2
+ class QueueSubscriber
3
+
4
+ include Sns
5
+ include Sqs
6
+
7
+ attr_reader :topic_arn, :queue
8
+
9
+ def self.subscribe(topic_id)
10
+ new(topic_id).subscribe
11
+ end
12
+
13
+ def initialize(topic_id)
14
+ @topic_id = topic_id
15
+ end
16
+
17
+ def subscribe
18
+ @topic_arn = TopicCreator.find_or_create(@topic_id)
19
+ @queue = QueueCreator.find_or_create(queue_name)
20
+ sns.subscribe(@topic_arn, @queue.arn, 'sqs')
21
+ end
22
+
23
+ private
24
+
25
+ def queue_name
26
+ @topic_id
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ require 'fog'
2
+
3
+ module Propono
4
+ module Sqs
5
+ private
6
+
7
+ def sqs
8
+ @sqs ||= Fog::AWS::SQS.new(
9
+ :aws_access_key_id => config.access_key,
10
+ :aws_secret_access_key => config.secret_key,
11
+ :region => config.queue_region
12
+ )
13
+ end
14
+
15
+ def config
16
+ Configuration.instance
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,12 @@
1
+ module Propono
2
+
3
+ module Subscriber
4
+ def self.subscribe_by_queue(topic)
5
+ QueueSubscriber.subscribe(topic)
6
+ end
7
+
8
+ def self.subscribe_by_post(topic, endpoint)
9
+ PostSubscriber.subscribe(topic, endpoint)
10
+ end
11
+ end
12
+ end
@@ -14,8 +14,8 @@ module Propono
14
14
  end
15
15
 
16
16
  def find_or_create
17
- create_topic_result = sns.create_topic(@topic_id)
18
- body = create_topic_result.body
17
+ result = sns.create_topic(@topic_id)
18
+ body = result.body
19
19
  body.fetch('TopicArn') { raise TopicCreatorError.new("No TopicArn returned from SNS") }
20
20
  end
21
21
  end
@@ -1,3 +1,3 @@
1
1
  module Propono
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class PostSubscriberTest < Minitest::Test
5
+ def test_create_topic
6
+ topic = 'foobar'
7
+ TopicCreator.expects(:find_or_create).with(topic)
8
+ PostSubscriber.subscribe(topic, "foobar")
9
+ end
10
+
11
+ def test_subscribe_calls_subscribe
12
+ arn = "arn123"
13
+ endpoint = "http://meducation.net/some_queue_name"
14
+
15
+ TopicCreator.stubs(find_or_create: arn)
16
+
17
+ sns = mock()
18
+ sns.expects(:subscribe).with(arn, endpoint, 'http')
19
+ subscriber = PostSubscriber.new("Some topic", endpoint)
20
+ subscriber.stubs(sns: sns)
21
+ subscriber.subscribe
22
+ end
23
+
24
+ def test_it_correctly_uses_http_and_https
25
+ skip
26
+ end
27
+ end
28
+ end
29
+
@@ -15,16 +15,40 @@ module Propono
15
15
  Publisher.new.publish(topic, message)
16
16
  end
17
17
 
18
- def test_publish_should_call_sns_on_correct_topic
18
+ def test_publish_should_call_sns_on_correct_topic_and_message
19
+ topic = "topic123"
20
+ message = "message123"
21
+ topic_arn = "arn123"
22
+
23
+ TopicCreator.stubs(find_or_create: topic_arn)
24
+
25
+ sns = mock()
26
+ sns.expects(:publish).with(topic_arn, message)
27
+ publisher = Publisher.new
28
+ publisher.stubs(sns: sns)
29
+
30
+ publisher.publish(topic, message)
19
31
  end
20
32
 
21
- def test_publish_should_call_sns_with_message
33
+ def test_publish_should_propogate_exception_on_topic_creation_error
34
+ TopicCreator.stubs(:find_or_create).raises(TopicCreatorError)
35
+
36
+ assert_raises(TopicCreatorError) do
37
+ Publisher.publish("topic", "message")
38
+ end
22
39
  end
23
40
 
24
41
  def test_publish_creates_a_topic
25
42
  topic = "Malcs_topic"
43
+
26
44
  TopicCreator.expects(:find_or_create).with(topic)
27
- Publisher.new.publish(topic, "Foobar")
45
+
46
+ sns = mock()
47
+ sns.stubs(:publish)
48
+ publisher = Publisher.new
49
+ publisher.stubs(sns: sns)
50
+
51
+ publisher.publish(topic, "Foobar")
28
52
  end
29
53
 
30
54
  def test_publish_should_raise_exception_if_topic_is_nil
@@ -0,0 +1,41 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class QueueCreatorTest < Minitest::Test
5
+
6
+ def test_create_topic_called_on_sqs
7
+ sqs = mock()
8
+ sqs.expects(:create_queue).with("foobar").returns(mock(body: { "QueueUrl" => "Foobar"}))
9
+
10
+ creator = QueueCreator.new("foobar")
11
+ creator.stubs(sqs: sqs)
12
+
13
+ creator.find_or_create
14
+ end
15
+
16
+ def test_returns_url
17
+ url = "malcs_happy_queue"
18
+ result = mock(body: { "QueueUrl" => url})
19
+ sqs = mock(create_queue: result)
20
+
21
+ creator = QueueCreator.new("foobar")
22
+ creator.stubs(sqs: sqs)
23
+
24
+ queue = creator.find_or_create
25
+ assert_equal url, queue.url
26
+ end
27
+
28
+ def test_should_raise_exception_if_no_queue_returned
29
+ result = mock(body: {})
30
+ sqs = mock(create_queue: result)
31
+
32
+ creator = QueueCreator.new("foobar")
33
+ creator.stubs(sqs: sqs)
34
+
35
+ assert_raises QueueCreatorError do
36
+ creator.find_or_create
37
+ end
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,51 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class QueueSubscriberTest < Minitest::Test
5
+ def test_create_topic
6
+ topic = 'foobar'
7
+ TopicCreator.expects(:find_or_create).with(topic)
8
+ QueueSubscriber.subscribe(topic)
9
+ end
10
+
11
+ def test_sqs_create_is_called
12
+ topic = "Foobar"
13
+ subscriber = QueueSubscriber.new(topic)
14
+
15
+ TopicCreator.stubs(find_or_create: "1123")
16
+
17
+ sqs = mock()
18
+ sqs.expects(:create_queue).with(subscriber.send(:queue_name)).returns(mock(body: {'QueueUrl' => Fog::AWS::SQS::Mock::QueueUrl}))
19
+ QueueCreator.any_instance.stubs(sqs: sqs)
20
+
21
+ subscriber.subscribe
22
+ end
23
+
24
+ def test_subscriber_queue_name
25
+ skip
26
+ end
27
+
28
+ def test_subscribe_calls_subscribe
29
+ arn = "arn123"
30
+ queue_url =
31
+
32
+ TopicCreator.stubs(find_or_create: arn)
33
+ QueueCreator.stubs(find_or_create: Queue.new(Fog::AWS::SQS::Mock::QueueUrl))
34
+
35
+ sns = mock()
36
+ sns.expects(:subscribe).with(arn, Fog::AWS::SQS::Mock::QueueArn, 'sqs')
37
+ subscriber = QueueSubscriber.new("Some topic")
38
+ subscriber.stubs(sns: sns)
39
+ subscriber.subscribe
40
+ end
41
+
42
+ def test_subscribe_saves_queue
43
+ queue = Queue.new(Fog::AWS::SQS::Mock::QueueUrl)
44
+
45
+ QueueCreator.expects(:find_or_create).returns(queue)
46
+ subscriber = QueueSubscriber.new("Some Topic")
47
+ subscriber.subscribe
48
+ assert_equal queue, subscriber.queue
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class QueueTest < Minitest::Test
5
+ def test_intialization_sets_url
6
+ url = 'foobar'
7
+ queue = Queue.new(url)
8
+ assert url, queue.url
9
+ end
10
+
11
+ def test_arn
12
+ skip
13
+ end
14
+ end
15
+ end
16
+
data/test/sqs_test.rb ADDED
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class SqsTest < Minitest::Test
5
+ class SqsTestClass
6
+ include Sqs
7
+ end
8
+
9
+ def setup
10
+ config.access_key = "test-access-key"
11
+ config.secret_key = "test-secret-key"
12
+ config.queue_region = "us-east-1"
13
+ end
14
+
15
+ def test_sqs
16
+ Fog::AWS::SQS.expects(:new)
17
+ .with(:aws_access_key_id => 'test-access-key',
18
+ :aws_secret_access_key => 'test-secret-key',
19
+ :region => 'us-east-1')
20
+
21
+ SqsTestClass.new.send :sqs
22
+ end
23
+
24
+ private
25
+
26
+ def config
27
+ Configuration.instance
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,21 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class SubscriberTest < Minitest::Test
5
+
6
+ def test_subscribe_by_queue_calls_queue_subscriber
7
+ subscriber = QueueSubscriber.new("topic")
8
+ QueueSubscriber.expects(:new).with("topic").returns(subscriber)
9
+ QueueSubscriber.any_instance.expects(:subscribe)
10
+ Subscriber.subscribe_by_queue("topic")
11
+ end
12
+
13
+ def test_subscribe_by_post_calls_post_subscribe
14
+ subscriber = PostSubscriber.new("topic", 'endpoint')
15
+ PostSubscriber.expects(:new).with("topic", 'endpoint').returns(subscriber)
16
+ PostSubscriber.any_instance.expects(:subscribe)
17
+ Subscriber.subscribe_by_post("topic", "endpoint")
18
+ end
19
+
20
+ end
21
+ end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
1
4
  gem "minitest"
2
5
  require "minitest/autorun"
3
6
  require "minitest/pride"
@@ -8,3 +11,40 @@ lib = File.expand_path('../../lib', __FILE__)
8
11
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
9
12
 
10
13
  require "propono"
14
+
15
+ Fog.mock!
16
+
17
+ class Minitest::Test
18
+ def setup
19
+ Propono::Configuration.instance.access_key = "test-access-key"
20
+ Propono::Configuration.instance.secret_key = "test-secret-key"
21
+ Propono::Configuration.instance.queue_region = "us-east-1"
22
+ end
23
+ end
24
+
25
+ class Fog::AWS::SNS::Mock
26
+ def create_topic(*args)
27
+ foo = Object.new
28
+ class << foo
29
+ def body
30
+ {"TopicArn" => "FoobarFromTheMock"}
31
+ end
32
+ end
33
+ foo
34
+ end
35
+
36
+ def subscribe(topic_arn, arn_or_url, type)
37
+ end
38
+ end
39
+
40
+ require 'fog'
41
+ class Fog::AWS::SQS::Mock
42
+ def create_queue(*args)
43
+ end
44
+ end
45
+
46
+ Fog::AWS::SQS::Mock::QueueUrl = 'https://meducation.net/foobar'
47
+ Fog::AWS::SQS::Mock::QueueArn = 'FoobarArn'
48
+ data = {'Attributes' => {"QueueArn" => Fog::AWS::SQS::Mock::QueueArn}}
49
+ queues = Fog::AWS::SQS::Mock.data["us-east-1"]["test-access-key"][:queues]
50
+ queues[Fog::AWS::SQS::Mock::QueueUrl] = data
@@ -15,8 +15,8 @@ module Propono
15
15
 
16
16
  def test_returns_arn
17
17
  arn = "malcs_happy_arn"
18
- create_topic_result = mock(body: { "TopicArn" => arn})
19
- sns = mock(create_topic: create_topic_result)
18
+ result = mock(body: { "TopicArn" => arn})
19
+ sns = mock(create_topic: result)
20
20
 
21
21
  creator = TopicCreator.new("foobar")
22
22
  creator.stubs(sns: sns)
@@ -25,8 +25,8 @@ module Propono
25
25
  end
26
26
 
27
27
  def test_should_raise_exception_if_no_arn_returned
28
- create_topic_result = mock(body: {})
29
- sns = mock(create_topic: create_topic_result)
28
+ result = mock(body: {})
29
+ sns = mock(create_topic: result)
30
30
 
31
31
  creator = TopicCreator.new("foobar")
32
32
  creator.stubs(sns: sns)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propono
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-10-15 00:00:00.000000000 Z
13
+ date: 2013-10-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fog
@@ -101,6 +101,7 @@ extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
103
  - .gitignore
104
+ - .travis.yml
104
105
  - CONTRIBUTING.md
105
106
  - Gemfile
106
107
  - LICENCE.md
@@ -108,14 +109,26 @@ files:
108
109
  - Rakefile
109
110
  - lib/propono.rb
110
111
  - lib/propono/configuration.rb
112
+ - lib/propono/post_subscriber.rb
111
113
  - lib/propono/publisher.rb
114
+ - lib/propono/queue.rb
115
+ - lib/propono/queue_creator.rb
116
+ - lib/propono/queue_subscriber.rb
112
117
  - lib/propono/sns.rb
118
+ - lib/propono/sqs.rb
119
+ - lib/propono/subscriber.rb
113
120
  - lib/propono/topic_creator.rb
114
121
  - lib/propono/version.rb
115
122
  - propono.gemspec
116
123
  - test/configuration_test.rb
124
+ - test/post_subscriber_test.rb
117
125
  - test/publisher_test.rb
126
+ - test/queue_creator_test.rb
127
+ - test/queue_subscriber_test.rb
128
+ - test/queue_test.rb
118
129
  - test/sns_test.rb
130
+ - test/sqs_test.rb
131
+ - test/subscriber_test.rb
119
132
  - test/test_helper.rb
120
133
  - test/topic_creator_test.rb
121
134
  homepage: ''
@@ -133,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
146
  version: '0'
134
147
  segments:
135
148
  - 0
136
- hash: -1315307569303523686
149
+ hash: 1295735887844079183
137
150
  required_rubygems_version: !ruby/object:Gem::Requirement
138
151
  none: false
139
152
  requirements:
@@ -142,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
155
  version: '0'
143
156
  segments:
144
157
  - 0
145
- hash: -1315307569303523686
158
+ hash: 1295735887844079183
146
159
  requirements: []
147
160
  rubyforge_project:
148
161
  rubygems_version: 1.8.25
@@ -151,7 +164,13 @@ specification_version: 3
151
164
  summary: General purpose pub/sub library built on top of AWS SNS and SQS
152
165
  test_files:
153
166
  - test/configuration_test.rb
167
+ - test/post_subscriber_test.rb
154
168
  - test/publisher_test.rb
169
+ - test/queue_creator_test.rb
170
+ - test/queue_subscriber_test.rb
171
+ - test/queue_test.rb
155
172
  - test/sns_test.rb
173
+ - test/sqs_test.rb
174
+ - test/subscriber_test.rb
156
175
  - test/test_helper.rb
157
176
  - test/topic_creator_test.rb