propono 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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