bi-frost 0.1.4 → 0.2.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: 9bae9c137149abf5f29d00b38d46763ead852eec
4
- data.tar.gz: 6dbd4e1370c6b62ce67bd7df6826b0a8d75e664b
3
+ metadata.gz: 5c7ef1811b993361b82e924590621cd7acbcd263
4
+ data.tar.gz: b365ca8848c557b296fbef2ad330746e70472aa5
5
5
  SHA512:
6
- metadata.gz: e07411b6991e054810097254fc39d2e5745ff2fccb2a75bdb0e9c4051c269feed887094c4e2eaef128a37d4978ba453c263da0c903e199163d6e4b7b1b0f3ea0
7
- data.tar.gz: 105f3f014d5fb0d5444f03b6c258eb9fdc2e0cbaf65b97089b87167ddf0f728f9a78dda8dc7356736b043f1bc57d8f087e1eaec197cad6cd2339be00e9285962
6
+ metadata.gz: 933abde1218ef15a966004dcded976de5076fb5eb7b4e97fa316dc957e55e8009e1058758a1f6c4cb78649a5e5c522238bd8a6e9387e340714dff541a4d49fd7
7
+ data.tar.gz: c0b8558f903e565ce019cdc833e9b99a604ceb1d144653b82a7a4152a6b350b21fa1eb287c992dce98836e60eae8e179b155dee61d11d977d2c7b7cfcc5f4b67
data/README.md CHANGED
@@ -56,31 +56,29 @@ subscriber = Bifrost::Subscriber.new('new_subscriber')
56
56
  topic.add_subscriber(subscriber)
57
57
  ```
58
58
 
59
- Each topic can only have a unique list of subscribers, a subscriber cannot be added to a topic more than once. When a subscriber is added to
60
- a topic this function will return a true or false indicating success of the add.
59
+ Each topic can only have a unique list of subscribers, a subscriber cannot be added to a topic more than once. When a subscriber is added to a topic this function will return a true or false indicating success of the add.
61
60
 
62
61
  To post a message to a topic;
63
62
 
64
63
  ```ruby
65
64
  topic = Bifrost::Topic.new('topic_name')
66
65
  message = Bifrost::Message.new(content: 'some data')
67
- message.post_to(topic)
66
+ message.publish(topic)
68
67
  ```
69
68
 
70
- This function returns a `true` or `false` indicating the success of the message delivery. This method is synchronous. Each message has an
71
- identifier which gets sets upon successful delivery only.
69
+ This function returns a `true` or `false` indicating the success of the message delivery. This method is synchronous. Each message has an identifier which gets sets upon successful delivery only.
72
70
 
73
71
  A message can also be optionally published with a subject;
74
72
 
75
73
  ```ruby
76
74
  topic = Bifrost::Topic.new('topic_name')
77
75
  message = Bifrost::Message.new(content: 'some data', 'message subject')
78
- message.post_to(topic)
76
+ message.publish(topic)
79
77
  ```
80
78
 
81
- Subscribers in the Bifrost are [actors](http://http://doc.akka.io/docs/akka/2.4/general/actors.html), these actors run in
82
- their own threads. At present the Bifrost does not support thread pools, this is something we are investigating and are
83
- hoping to add at some point. In the Bifrost each actor is referred to as a `worker`. A worker is designed to receive
79
+ An alternative method named `publish!` also exists. This method raises an error is a message cannot be delivered. The error raised is `Bifrost::Exceptions::MessageDeliveryError`. If the message is successfully delivered with the method `publish!`, the messages `UUID` is returned in the call.
80
+
81
+ Subscribers in the Bifrost are [actors](http://http://doc.akka.io/docs/akka/2.4/general/actors.html), these actors run in their own threads. At present the Bifrost does not support thread pools, this is something we are investigating and are hoping to add at some point. In the Bifrost each actor is referred to as a `worker`. A worker is designed to receive
84
82
  messages published to a particular topic with a specific subscriber in mind (refer to the fan-out comment earlier).
85
83
 
86
84
  Workers are added to the Bifrost via the manager. The manager is what activates the workers in the Bifrost environment.
data/lib/bifrost.rb CHANGED
@@ -5,11 +5,16 @@ require 'bifrost/topic'
5
5
  require 'bifrost/subscriber'
6
6
  require 'bifrost/manager'
7
7
  require 'bifrost/worker'
8
+
9
+ require 'bifrost/exceptions/duplicate_subscriber_error'
10
+ require 'bifrost/exceptions/invalid_worker_definition_error'
11
+ require 'bifrost/exceptions/message_delivery_error'
12
+ require 'bifrost/exceptions/unsupported_lambda_error'
13
+
8
14
  require 'celluloid'
9
15
 
10
16
  # Bifrost is a pub/sub gem built on top of the Azure MessageBus system
11
17
  module Bifrost
12
-
13
18
  # Workers and the infrastructure can log using the standard level of granularity affored to any
14
19
  # standard logger (i.e. info, debug, error levels etc)
15
20
  def self.logger=(log_provider)
data/lib/bifrost/bus.rb CHANGED
@@ -47,4 +47,4 @@ module Bifrost
47
47
  ENV['AZURE_BUS_KEY_SECRET']
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -0,0 +1,6 @@
1
+ module Bifrost
2
+ module Exceptions
3
+ class MessageDeliveryError < StandardError
4
+ end
5
+ end
6
+ end
@@ -17,23 +17,38 @@ module Bifrost
17
17
  end
18
18
 
19
19
  # A message can be posted to a particular topic
20
- def post_to(topic)
20
+ def publish(topic)
21
21
  if topic.exists?
22
- message = create_brokered_message
23
- @bus.interface.send_topic_message(topic.name, message)
24
- update_message_state_to_delivered(message)
22
+ send_message(topic, create_brokered_message)
25
23
  true
26
24
  else
27
25
  false
28
26
  end
29
27
  end
30
28
 
29
+ # A message can be posted to a particular topic, if the message is succssfully delivered
30
+ # we return a unique identifier for the message
31
+ def publish!(topic)
32
+ if topic.exists?
33
+ send_message(topic, create_brokered_message)
34
+ message_id
35
+ else
36
+ raise Bifrost::Exceptions::MessageDeliveryError, "Could not post message to #{topic}"
37
+ end
38
+ end
39
+
31
40
  private
32
41
 
42
+ # Create the message and attempt to deliver It
43
+ def send_message(topic, message)
44
+ @bus.interface.send_topic_message(topic.name, message)
45
+ update_message_state_to_delivered(message)
46
+ end
47
+
33
48
  # Create the brokered message
34
49
  def create_brokered_message
35
50
  message = Azure::ServiceBus::BrokeredMessage.new(subject, message: body)
36
- message.correlation_id = SecureRandom.hex
51
+ message.correlation_id = SecureRandom.uuid
37
52
  message
38
53
  end
39
54
 
data/lib/bifrost/topic.rb CHANGED
@@ -33,6 +33,13 @@ module Bifrost
33
33
  end
34
34
  end
35
35
 
36
+ # This method returns a list of subscribers currently defined on the topic
37
+ def subscribers
38
+ @bus.interface.list_subscriptions(name).map do |s|
39
+ Subscriber.new(s.name)
40
+ end
41
+ end
42
+
36
43
  # A new subscriber can be added to a topic
37
44
  def add_subscriber(subscriber)
38
45
  if exists?
@@ -63,8 +70,8 @@ module Bifrost
63
70
  end
64
71
  end
65
72
 
66
- def ==(another_topic)
67
- self.name == another_topic.name && self.class == another_topic.class
73
+ def ==(other)
74
+ name == other.name && self.class == other.class
68
75
  end
69
76
 
70
77
  # Topics are self aware, and know if they exist or not, but only with the help
@@ -72,5 +79,9 @@ module Bifrost
72
79
  def exists?
73
80
  @bus.topic_exists?(self)
74
81
  end
82
+
83
+ def to_s
84
+ name
85
+ end
75
86
  end
76
87
  end
@@ -5,11 +5,11 @@ module Bifrost
5
5
  MAJOR_VERSION = 0
6
6
 
7
7
  # The minor version of Bifrost, updated for new feature releases.
8
- MINOR_VERSION = 1
8
+ MINOR_VERSION = 2
9
9
 
10
10
  # The patch version of Bifrost, updated only for bug fixes from the last
11
11
  # feature release.
12
- PATCH_VERSION = 4
12
+ PATCH_VERSION = 0
13
13
 
14
14
  # The full version as a string.
15
15
  VERSION = "#{MAJOR_VERSION}.#{MINOR_VERSION}.#{PATCH_VERSION}".freeze
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Bifrost::Bus do
4
- let(:bus) { Bifrost::Bus.new }
4
+ let(:bus) { Bifrost::Bus.new }
5
5
 
6
6
  context 'for an undefined topic' do
7
7
  it 'should return false for defined?' do
@@ -8,7 +8,8 @@ describe Bifrost::Message do
8
8
  it { is_expected.to respond_to(:status) }
9
9
  it { is_expected.to respond_to(:message_id) }
10
10
  it { is_expected.to respond_to(:body) }
11
- it { is_expected.to respond_to(:post_to) }
11
+ it { is_expected.to respond_to(:publish) }
12
+ it { is_expected.to respond_to(:publish!) }
12
13
 
13
14
  context 'which is initialized' do
14
15
  it 'should be in an undelivered status' do
@@ -21,18 +22,39 @@ describe Bifrost::Message do
21
22
  expect(new_message).to_not be_nil
22
23
  end
23
24
 
24
- it 'should be postable to a valid topic' do
25
- topic = Bifrost::Topic.new('valid-topic')
26
- topic.save
27
- topic.add_subscriber(Bifrost::Subscriber.new('new_subscriber'))
28
- expect(message.post_to(topic)).to be_truthy
29
- expect(message.status).to eq(:delivered)
30
- expect(message.message_id).not_to be_nil
31
- topic.delete
25
+ describe 'publish' do
26
+ it 'should publish to a valid topic' do
27
+ topic = Bifrost::Topic.new('valid-topic')
28
+ topic.save
29
+ topic.add_subscriber(Bifrost::Subscriber.new('new_subscriber'))
30
+ expect(message.publish(topic)).to be_truthy
31
+ expect(message.status).to eq(:delivered)
32
+ expect(message.message_id).not_to be_nil
33
+ topic.delete
34
+ end
35
+
36
+ it 'should not be postable to an invalid topic' do
37
+ topic = Bifrost::Topic.new('invalid-topic') # A topic that is neither saved, nor with no subscribers is semantically invalid
38
+ expect(message.publish(topic)).to be_falsey
39
+ end
32
40
  end
33
41
 
34
- it 'should not be postable to an invalid topic' do
35
- topic = Bifrost::Topic.new('invalid-topic') # A topic that is neither saved, nor with no subscribers is semantically invalid
36
- expect(message.post_to(topic)).to be_falsey
42
+ describe 'publish!' do
43
+ it 'should publish to a valid topic and return the message id' do
44
+ topic = Bifrost::Topic.new('valid-topic')
45
+ topic.save
46
+ topic.add_subscriber(Bifrost::Subscriber.new('new_subscriber'))
47
+ response = message.publish!(topic)
48
+ expect(response).not_to be_nil
49
+ expect(message.status).to eq(:delivered)
50
+ expect(message.message_id).not_to be_nil
51
+ expect(response).to eq(message.message_id)
52
+ topic.delete
53
+ end
54
+
55
+ it 'should raise an exception upon publish to an invalid topic' do
56
+ topic = Bifrost::Topic.new('invalid-topic')
57
+ expect { message.publish!(topic) }.to raise_error(Bifrost::Exceptions::MessageDeliveryError)
58
+ end
37
59
  end
38
60
  end
@@ -15,6 +15,15 @@ describe Bifrost::Topic do
15
15
  expect { invalid_topic.save }.to raise_error(TypeError)
16
16
  end
17
17
 
18
+ it 'should have a friendly name' do
19
+ expect(topic.to_s).to eq('topic_name')
20
+ end
21
+
22
+ it 'should not accept names with spaces in them' do
23
+ invalid_topic = Bifrost::Topic.new('topic name')
24
+ expect { invalid_topic.save }.to raise_error(URI::InvalidURIError)
25
+ end
26
+
18
27
  describe 'equality' do
19
28
  it 'should return true for the same object' do
20
29
  expect(topic).to eq(topic)
@@ -32,10 +41,13 @@ describe Bifrost::Topic do
32
41
  end
33
42
 
34
43
  context 'for an undefined topic' do
35
- it 'should persist the topic' do
36
- new_topic = Bifrost::Topic.new('new_topic_name')
37
- expect(new_topic.save).to be_truthy
38
- expect(new_topic.delete).to be_truthy
44
+
45
+ describe 'save' do
46
+ it 'should persist the topic and return a binary value' do
47
+ new_topic = Bifrost::Topic.new('new_topic_name')
48
+ expect(new_topic.save).to be_truthy
49
+ expect(new_topic.delete).to be_truthy
50
+ end
39
51
  end
40
52
 
41
53
  it 'should return false for delete' do
@@ -56,16 +68,8 @@ describe Bifrost::Topic do
56
68
  context 'for a defined topic' do
57
69
  let(:new_topic) { Bifrost::Topic.new('test_donotdelete') }
58
70
 
59
- before(:all) do
60
- bus = Bifrost::Bus.new
61
- tp = Bifrost::Topic.new('test_donotdelete')
62
- tp.save unless bus.topic_exists?(tp)
63
- end
64
-
65
- after(:all) do
66
- bus = Bifrost::Bus.new
67
- tp = Bifrost::Topic.new('test_donotdelete')
68
- tp.delete if bus.topic_exists?(tp)
71
+ before(:each) do
72
+ new_topic.save
69
73
  end
70
74
 
71
75
  it 'should return false for save' do
@@ -88,10 +92,24 @@ describe Bifrost::Topic do
88
92
  expect(new_topic.add_subscriber(subscriber)).to be_truthy
89
93
  expect(new_topic.add_subscriber(subscriber)).to be_falsey
90
94
  end
91
- end
92
95
 
93
- it 'should not accept names with spaces in them' do
94
- invalid_topic = Bifrost::Topic.new('topic name')
95
- expect { invalid_topic.save }.to raise_error(URI::InvalidURIError)
96
+ context 'with no subscribers' do
97
+ it 'should return no subscribers' do
98
+ expect(new_topic.subscribers).to be_empty
99
+ end
100
+ end
101
+
102
+ context 'with subscribers' do
103
+ before(:each) do
104
+ subscriber_a = Bifrost::Subscriber.new('new_subscriber_a')
105
+ subscriber_b = Bifrost::Subscriber.new('new_subscriber_b')
106
+ new_topic.add_subscriber(subscriber_a)
107
+ new_topic.add_subscriber(subscriber_b)
108
+ end
109
+
110
+ it 'should return a list of it\'s subscribers' do
111
+ expect(new_topic.subscribers.size).to eq(2)
112
+ end
113
+ end
96
114
  end
97
115
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'bifrost/exceptions/unsupported_lambda_error'
3
2
  require 'bifrost'
4
3
 
5
4
  describe Bifrost::Worker do
@@ -33,7 +32,7 @@ describe Bifrost::Worker do
33
32
  subscriber = Bifrost::Subscriber.new('subscriber')
34
33
  topic.add_subscriber(subscriber)
35
34
  msg = Bifrost::Message.new([item1: { data: 2 }, item2: { more_data: 3 }])
36
- msg.post_to(topic)
35
+ msg.publish(topic)
37
36
  expect(msg.status).to eq(:delivered)
38
37
  expect(msg.message_id).not_to be_nil
39
38
  worker.async.run
data/spec/spec_helper.rb CHANGED
@@ -44,4 +44,16 @@ RSpec.configure do |config|
44
44
  # inherited by the metadata hash of host groups and examples, rather than
45
45
  # triggering implicit auto-inclusion in groups with matching metadata.
46
46
  config.shared_context_metadata_behavior = :apply_to_host_groups
47
+
48
+ # Clear the bifrost before running each spec
49
+ config.before(:example) do
50
+ bus = Bifrost::Bus.new
51
+ bus.topics.each(&:delete)
52
+ end
53
+
54
+ # Clear the bifrost after running specs
55
+ config.after(:suite) do
56
+ bus = Bifrost::Bus.new
57
+ bus.topics.each(&:delete)
58
+ end
47
59
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bi-frost
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shirren Premaratne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-02 00:00:00.000000000 Z
11
+ date: 2016-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: azure
@@ -164,6 +164,7 @@ files:
164
164
  - lib/bifrost/entity.rb
165
165
  - lib/bifrost/exceptions/duplicate_subscriber_error.rb
166
166
  - lib/bifrost/exceptions/invalid_worker_definition_error.rb
167
+ - lib/bifrost/exceptions/message_delivery_error.rb
167
168
  - lib/bifrost/exceptions/unsupported_lambda_error.rb
168
169
  - lib/bifrost/manager.rb
169
170
  - lib/bifrost/message.rb