carnivore-rabbitmq 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ # v0.1.0
2
+ * Initial release
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,25 @@
1
+ # Contributing
2
+
3
+ ## Branches
4
+
5
+ ### `master` branch
6
+
7
+ The master branch is the current stable released version.
8
+
9
+ ### `develop` branch
10
+
11
+ The develop branch is the current edge of development.
12
+
13
+ ## Pull requests
14
+
15
+ * https://github.com/carnivore-rb/carnivore-rabbitmq/pulls
16
+
17
+ Please base all pull requests of the `develop` branch. Merges to
18
+ `master` only occur through the `develop` branch. Pull requests
19
+ based on `master` will likely be cherry picked.
20
+
21
+ ## Issues
22
+
23
+ Need to report an issue? Use the github issues:
24
+
25
+ * https://github.com/carnivore-rb/carnivore-rabbitmq/issues
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2014 Chris Roberts
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Carnivore RabbitMQ
2
+
3
+ Provides RabbitMQ `Carnivore::Source`
4
+
5
+ # Usage
6
+
7
+ ## RabbitMQ
8
+
9
+ ```ruby
10
+ require 'carnivore'
11
+ require 'carnivore-rabbitmq'
12
+
13
+ Carnivore.configure do
14
+ source = Carnivore::Source.build(
15
+ :type => :rabbitmq,
16
+ :args => {
17
+ :connection => {
18
+ :connection => :args
19
+ },
20
+ :exchange => 'e_name',
21
+ :queue => 'q_name'
22
+ }
23
+ )
24
+ end
25
+ ```
26
+
27
+ # Info
28
+ * Carnivore: https://github.com/heavywater/carnivore
29
+ * Repository: https://github.com/heavywater/carnivore-rabbitmq
30
+ * IRC: Freenode @ #heavywater
@@ -0,0 +1,45 @@
1
+ module Carnivore
2
+ class Source
3
+ class Rabbitmq
4
+ # Message collector
5
+ class MessageCollector
6
+
7
+ include Celluloid
8
+ include Carnivore::Utils::Logging
9
+
10
+ # @return [Bunny::Queue, MarchHare::Queue] remote queue
11
+ attr_reader :queue
12
+ # @return [Queue] local message bucket
13
+ attr_reader :message_queue
14
+ # @return [Celluloid::Actor] actor to notify
15
+ attr_reader :notify
16
+
17
+ # Create new instance
18
+ #
19
+ # @param queue [Bunny::Queue, MarchHare::Queue] remote queue
20
+ # @param message_queue [Queue] local message bucket
21
+ # @param notify [Celluloid::Actor] actor to notify
22
+ def initialize(queue, message_queue, notify)
23
+ @queue = queue
24
+ @message_queue = message_queue
25
+ @notify = notify
26
+ end
27
+
28
+ # Collect messages from remote queue
29
+ #
30
+ # @return [TrueClass]
31
+ def collect_messages
32
+ queue.subscribe(:block => true, :ack => true) do |info, metadata, payload|
33
+ debug "Message received: #{payload.inspect}"
34
+ debug "Message info: #{info.inspect}"
35
+ debug "Message metadata: #{metadata.inspect}"
36
+ message_queue << {:info => info, :metadata => metadata, :payload => payload}
37
+ notify.signal(:new_messages)
38
+ end
39
+ true
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,143 @@
1
+ require 'carnivore-rabbitmq'
2
+
3
+ module Carnivore
4
+ class Source
5
+
6
+ # RabbitMQ based carnivore source
7
+ class Rabbitmq < Source
8
+
9
+ autoload :MessageCollector, 'carnivore-rabbitmq/message_collector'
10
+
11
+ # @return [Smash] initialization arguments
12
+ attr_reader :args
13
+ # @return [MarchHare::Session, Bunny::Session] current connection
14
+ attr_reader :connection
15
+ # @return [MarchHare::Exchange, Bunny::Exchange] current exchange
16
+ attr_reader :exchange
17
+ # @return [MarchHare::Channel, Bunny::Channel] current channel
18
+ attr_reader :channel
19
+ # @return [MarchHare::Queue, Bunny::Queue] current queue
20
+ attr_reader :queue
21
+ # @return [Queue] message queue
22
+ attr_reader :message_queue
23
+ # @return [Carnviore::Source::Rabbitmq::MessageCollector] message collector
24
+ attr_reader :message_collector
25
+
26
+ trap_exit :collector_failure
27
+ finalizer :collector_teardown
28
+
29
+ # RabbitMQ source setup
30
+ #
31
+ # @param args [Hash] initialization configuration
32
+ # @option args [String] :queue name of queue
33
+ # @option args [String] :exchange name of exchange
34
+ # @option args [Hash] :connection configuration hash for connection
35
+ # @option args [String, Symbol] :force_library :bunny or :march_hare
36
+ def setup(args={})
37
+ require 'carnivore-rabbitmq/message_collector'
38
+ @args = args.dup
39
+ @message_queue = Queue.new
40
+ @queue_name = args[:queue]
41
+ @exchange_name = args[:exchange]
42
+ @notifier = Celluloid::Signals.new
43
+ debug "Creating Rabbitmq source instance <#{name}>"
44
+ end
45
+
46
+ # Connect to the remote server
47
+ def connect
48
+ establish_connection
49
+ start_collector
50
+ end
51
+
52
+ # Start the message collection
53
+ def start_collector
54
+ @message_collector = MessageCollector.new(queue, message_queue, current_actor)
55
+ self.link message_collector
56
+ message_collector.async.collect_messages
57
+ end
58
+
59
+ # Restart collector if unexpectedly failed
60
+ #
61
+ # @param object [Actor] crashed actor
62
+ # @param reason [Exception, NilClass]
63
+ def collector_failure(object, reason)
64
+ if(reason && object == message_collector)
65
+ error "Message collector unexpectedly failed: #{reason} (restarting)"
66
+ start_collector
67
+ end
68
+ end
69
+
70
+ # Destroy message collector
71
+ #
72
+ # @return [TrueClass]
73
+ def collector_teardown
74
+ connection.close
75
+ if(message_collector.alive?)
76
+ message_collector.terminate
77
+ end
78
+ true
79
+ end
80
+
81
+ # Establish connection to remote server and setup
82
+ #
83
+ # @return [MarchHare::Session, Bunny::Session]
84
+ def establish_connection
85
+ unless(args[:connection])
86
+ abort KeyError.new "No configuration defined for connection type (#{connection_library})"
87
+ end
88
+ connection_args = Carnivore::Utils.symbolize_hash(args[:connection])
89
+ case connection_library
90
+ when :bunny
91
+ require 'bunny'
92
+ @connection = Bunny.new(connection_args)
93
+ when :march_hare
94
+ require 'march_hare'
95
+ @connection = MarchHare.new(connection_args)
96
+ else
97
+ abort ArgumentError.new("No valid connection arguments defined (:bunny or :march_hare must be defined)")
98
+ end
99
+ connection.start
100
+ @channel = connection.create_channel
101
+ @exchange = channel.topic(args[:exchange])
102
+ @queue = channel.queue(args[:queue], :auto_delete => false).bind(exchange) # TODO: Add topic key
103
+ @connection
104
+ end
105
+
106
+ # Receive payload from connection
107
+ #
108
+ # @return [Hash] payload
109
+ def receive(*_)
110
+ while(message_queue.empty?)
111
+ wait(:new_messages)
112
+ end
113
+ message_queue.pop
114
+ end
115
+
116
+ # Transmit payload to connection
117
+ #
118
+ # @param payload [Object]
119
+ def transmit(payload, *_)
120
+ payload = MultiJson.dump(payload) unless payload.is_a?(String)
121
+ queue.publish(payload)
122
+ end
123
+
124
+ # Confirm message processing
125
+ #
126
+ # @param message [Carnivore::Message]
127
+ def confirm(message)
128
+ info "Confirming message #{message}"
129
+ channel.acknowledge(message[:message][:info].delivery_tag, false)
130
+ end
131
+
132
+ # @return [Symbol] connection library to utilize
133
+ def connection_library
134
+ if(args[:force_library])
135
+ args[:force_library].to_sym
136
+ else
137
+ RUBY_PLATFORM == 'java' ? :march_hare : :bunny
138
+ end
139
+ end
140
+
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,9 @@
1
+ module Carnivore
2
+ module Rabbitmq
3
+ # Custom version class
4
+ class Version < Gem::Version
5
+ end
6
+ # Current version of library
7
+ VERSION = Version.new('0.1.0')
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'carnivore-rabbitmq/version'
2
+ require 'carnivore'
3
+
4
+ module Carnivore
5
+ class Source
6
+ autoload :Rabbitmq, 'carnivore-rabbitmq/rabbitmq'
7
+ end
8
+ end
9
+
10
+ Carnivore::Source.provide(:rabbitmq, 'carnivore-rabbitmq/rabbitmq')
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carnivore-rabbitmq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Roberts
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-05-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: carnivore
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.1.8
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.1.8
30
+ - !ruby/object:Gem::Dependency
31
+ name: bunny
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Carnivore RabbitMQ source
47
+ email: code@chrisroberts.org
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - lib/carnivore-rabbitmq/version.rb
53
+ - lib/carnivore-rabbitmq/message_collector.rb
54
+ - lib/carnivore-rabbitmq/rabbitmq.rb
55
+ - lib/carnivore-rabbitmq.rb
56
+ - README.md
57
+ - CHANGELOG.md
58
+ - CONTRIBUTING.md
59
+ - LICENSE
60
+ homepage: https://github.com/heavywater/carnivore-rabbitmq
61
+ licenses:
62
+ - Apache 2.0
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 1.8.24
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Message processing source
85
+ test_files: []
86
+ has_rdoc: