philotic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0d1256a8211bd2888c9d9d9652fe4a6fc89de284
4
+ data.tar.gz: 20e5c1a6ffca4a788bafbc283bc3bcfbd3a868bc
5
+ SHA512:
6
+ metadata.gz: 7b7f720591f38592197ebca75e7d3cb5440d6659c87b43aa99ed04d5ce3f92c4983721f1c1ef8e91387665095a9b30f0771d6073d4b5f75d4a83d056bf032d22
7
+ data.tar.gz: ea4267f99564ad426015b55b62ccefe22365a02f1ab8a28f35f3372e28a0c53f3116a1a6f576efd38bb77eddbf07ad493d0329a16b89b9bbbc57edb7d6df270c
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .project
19
+ philotic.yml
20
+ philotic_queues.yml
21
+ .idea/
22
+ log/*.log
23
+ .rvmrc
24
+ .ruby-version
25
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=progress
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.0
5
+ - 2.0.0
6
+ - jruby-19mode
7
+ - ruby-head
8
+ script:
9
+ - bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in philotic.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'pry'
8
+ gem 'rake'
9
+ gem 'rspec'
10
+ gem 'timecop'
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nathan Keyes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # Philotic
2
+
3
+ Lightweight, opinionated wrapper for using RabbitMQ headers exchanges
4
+
5
+ [![Build Status](https://travis-ci.org/nkeyes/philotic.png?branch=master)](https://travis-ci.org/nkeyes/philotic)
6
+
7
+ Check out the [examples](https://github.com/nkeyes/philotic/tree/master/examples).
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup :default, :test, :development
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ require 'rspec/core/rake_task'
8
+
9
+ require 'philotic/tasks'
10
+
11
+ RSpec::Core::RakeTask.new(:spec) do |spec|
12
+ spec.pattern = 'spec/**/*_spec.rb'
13
+ end
14
+
15
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
16
+ spec.pattern = 'spec/**/*_spec.rb'
17
+ spec.rcov = true
18
+ end
19
+
20
+ Dir["tasks/**/*.rake"].each { |ext| load ext }
21
+
22
+ task :spec
23
+ task default: :spec
24
+
@@ -0,0 +1,13 @@
1
+ # Philotic Examples
2
+ Read the code, yo!
3
+
4
+ ## (Re)Initializing Named Queues
5
+ Any project that includes Philotic can include the `philotic:init_queues[path/to/named_queues.yml]` task.
6
+
7
+ For example:
8
+ ```bash
9
+ PHILOTIC_RABBIT_HOST=localhost bundle exec rake eb:init_queues[path/to/named_queues.yml]
10
+ ```
11
+
12
+
13
+
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path( '../../../lib', __FILE__ )
3
+ $stdout.sync = true
4
+
5
+ require 'philotic'
6
+
7
+ EventMachine.run do
8
+ # hit Control + C to stop
9
+ Signal.trap("INT") { EventMachine.stop }
10
+ Signal.trap("TERM") { EventMachine.stop }
11
+
12
+ queue_after_initialize_handler = Proc.new do |q|
13
+ Philotic.logger.info "Queue '#{q.name}' initialized: #{q.bindings}"
14
+ end
15
+ # consume ansible + subspace + new_message events
16
+ ansible_arguments = {
17
+ "x-match" => :all,
18
+ philotic_product: :ansible,
19
+ philotic_component: :subspace,
20
+ philotic_event_type: :new_message,
21
+ }
22
+ Philotic.initialize_named_queue!('ansible.new_messages', ansible_arguments, &queue_after_initialize_handler)
23
+
24
+
25
+ EM.add_timer(5) { EM.stop }
26
+ end
@@ -0,0 +1,6 @@
1
+ # consume ansible + subspace + new_message events
2
+ ansible.new_messages:
3
+ - philotic_product: ansible
4
+ philotic_component: subspace
5
+ philotic_event_type: new_message
6
+ x-match: all
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path( '../../../lib', __FILE__ )
3
+ $stdout.sync = true
4
+
5
+ require 'philotic'
6
+ require 'rake'
7
+
8
+ require 'philotic/tasks'
9
+ # equivelant of:
10
+ # rake eb:init_queues[examples/creating_named_queues/philotic_named_queues.yml]
11
+ Rake::Task["eb:init_queues"].invoke(File.join(File.dirname(__FILE__),".","philotic_named_queues.yml"))
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../../lib', __FILE__)
3
+ $stdout.sync = true
4
+
5
+ require 'pry'
6
+
7
+ require 'philotic'
8
+ require 'philotic/dummy_event'
9
+
10
+ EventMachine.run do
11
+ # hit Control + C to stop
12
+ #Signal.trap("INT") { EventMachine.stop }
13
+ #Signal.trap("TERM") { EventMachine.stop }
14
+
15
+
16
+ Philotic::Config.load_file(File.join(File.dirname(__FILE__), "../../", "philotic.yml"))
17
+
18
+ #Philotic::Config.message_return_handler = Proc.new { |basic_return, metadata, payload|
19
+ # p "overridden"
20
+ # Philotic.logger.warn "#{JSON.parse payload} was returned! reply_code = #{basic_return.reply_code}, reply_text = #{basic_return.reply_text}"
21
+ #}
22
+
23
+
24
+ Philotic::Connection.connect! do
25
+ def send_message number
26
+ dummy_event = Philotic::DummyEvent.new
27
+
28
+ dummy_event.philotic_firehose = true
29
+ dummy_event.philotic_product = 'rabbit'
30
+ dummy_event.philotic_component = 'speed_test'
31
+ dummy_event.philotic_event_type = 'ping'
32
+
33
+ dummy_event.subject = "Hey"
34
+ dummy_event.available = true
35
+ dummy_event.gender = [:F, :M].sample
36
+
37
+
38
+ dummy_event.message_metadata = {mandatory: true}
39
+ dummy_event.message_metadata = {app_id: 'PHX'}
40
+ dummy_event.message = "Message #{number}: Hey #{dummy_event.gender == :M ? 'dude' : 'dudette'}"
41
+ dummy_event.publish
42
+
43
+ EM.add_timer rand/10 do
44
+ send_message number + 1
45
+ end
46
+ end
47
+
48
+ send_message 1
49
+
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../../lib', __FILE__)
3
+ $stdout.sync = true
4
+
5
+ require 'philotic'
6
+
7
+ EventMachine.run do
8
+ # hit Control + C to stop
9
+ # Signal.trap("INT") { EventMachine.stop }
10
+ # Signal.trap("TERM") { EventMachine.stop }
11
+
12
+ Philotic::Config.load_file(File.join(File.dirname(__FILE__), "../../", "philotic.yml"))
13
+
14
+
15
+ Philotic::Subscriber.subscribe(philotic_fire_hose: true) do |metadata, payload|
16
+ p metadata.attributes
17
+ p payload
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../../lib', __FILE__)
3
+ $stdout.sync = true
4
+
5
+ require 'pry'
6
+ require 'philotic'
7
+
8
+ EventMachine.run do
9
+ # hit Control + C to stop
10
+ Signal.trap("INT") { EventMachine.stop }
11
+ Signal.trap("TERM") { EventMachine.stop }
12
+
13
+ Philotic::Config.load_file(File.join(File.dirname(__FILE__), "../../", "philotic.yml"))
14
+
15
+ # explicitly create named queues for this example
16
+ # ENV['INITIALIZE_NAMED_QUEUE'] must equal 'true' to run Philotic.initialize_named_queue!
17
+ ENV['INITIALIZE_NAMED_QUEUE'] = 'true'
18
+ Philotic.initialize_named_queue!('male_queue', :"x-match" => 'all', gender: :M, available: true) do
19
+ Philotic.initialize_named_queue!('female_queue', :"x-match" => 'all', gender: :F, available: true)
20
+ end
21
+
22
+ # give it time to actually create the queue, then subscribe
23
+ EM.add_timer(3) do
24
+ Philotic::Subscriber.subscribe('male_queue') do |metadata, payload|
25
+ p metadata.attributes
26
+ p payload
27
+ end
28
+ Philotic::Subscriber.subscribe('female_queue') do |metadata, payload|
29
+ p metadata.attributes
30
+ p payload
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path( '../../../lib', __FILE__ )
3
+ $stdout.sync = true
4
+
5
+ require 'pry'
6
+ require 'philotic'
7
+
8
+ EventMachine.run do
9
+ # hit Control + C to stop
10
+ Signal.trap("INT") { EventMachine.stop }
11
+ Signal.trap("TERM") { EventMachine.stop }
12
+
13
+ #explicitly create a named queue for this example
14
+ Philotic.initialize_named_queue!('test_queue', :"x-match" => 'any', gender: :M, available: true)
15
+
16
+ # give it time to actually create the queue, then subscribe
17
+ EM.add_timer(3) do
18
+ Philotic::Subscriber.subscribe('test_queue') do |metadata, payload|
19
+ p metadata.attributes
20
+ p payload
21
+ end
22
+ end
23
+ end
data/lib/philotic.rb ADDED
@@ -0,0 +1,144 @@
1
+ require 'awesome_print'
2
+ require 'active_support/all'
3
+
4
+ require 'pathname'
5
+
6
+ require 'logger'
7
+
8
+
9
+ module Philotic
10
+ mattr_accessor :logger
11
+ mattr_accessor :log_event_handler
12
+
13
+ CONNECTION_OPTIONS = [
14
+ :rabbit_host,
15
+ :connection_failed_handler,
16
+ :connection_loss_handler,
17
+ :timeout,
18
+ ]
19
+ EXCHANGE_OPTIONS = [
20
+ :exchange_name,
21
+ :message_return_handler,
22
+ ]
23
+ MESSAGE_OPTIONS = [
24
+ :routing_key,
25
+ :persistent,
26
+ # :immediate,
27
+ :mandatory,
28
+ :content_type,
29
+ :content_encoding,
30
+ :priority,
31
+ :message_id,
32
+ :correlation_id,
33
+ :reply_to,
34
+ :type,
35
+ :user_id,
36
+ :app_id,
37
+ :timestamp,
38
+ :expiration,
39
+ ]
40
+
41
+ PHILOTIC_HEADERS = [
42
+ :philotic_firehose,
43
+ :philotic_product,
44
+ :philotic_component,
45
+ :philotic_event_type,
46
+ ]
47
+
48
+ DEFAULT_NAMED_QUEUE_OPTIONS = {
49
+ auto_delete: false,
50
+ durable: true
51
+ }
52
+ DEFAULT_ANONYMOUS_QUEUE_OPTIONS = {
53
+ auto_delete: true,
54
+ durable: false
55
+ }
56
+
57
+ DEFAULT_SUBSCRIBE_OPTIONS = {}
58
+
59
+ def self.root
60
+ ::Pathname.new File.expand_path('../../', __FILE__)
61
+ end
62
+
63
+ def self.env
64
+ ENV['SERVICE_ENV'] || 'development'
65
+ end
66
+
67
+ def self.exchange
68
+ Philotic::Connection.exchange
69
+ end
70
+
71
+ def self.initialize_named_queue!(queue_name, config, &block)
72
+ config = config.deep_symbolize_keys
73
+
74
+
75
+ raise "ENV['INITIALIZE_NAMED_QUEUE'] must equal 'true' to run Philotic.initialize_named_queue!" unless ENV['INITIALIZE_NAMED_QUEUE'] == 'true'
76
+ connect! do
77
+ queue_options = DEFAULT_NAMED_QUEUE_OPTIONS.dup
78
+ queue_options.merge!(config[:options] || {})
79
+
80
+ AMQP.channel.queue(queue_name, queue_options) do |old_queue|
81
+ old_queue.delete do
82
+ Philotic::Connection.close do
83
+ connect! do
84
+ Philotic.logger.info "deleted old queue. queue:#{queue_name}"
85
+
86
+ bindings = Array(config[:bindings])
87
+
88
+ queue_exchange = config[:exchange] ? AMQP.channel.headers(config[:exchange], durable: true) : exchange
89
+
90
+ AMQP.channel.queue(queue_name, queue_options) do |q|
91
+ Philotic.logger.info "Created queue. queue:#{q.name}"
92
+ bindings.each_with_index do |arguments, arguments_index|
93
+ q.bind(queue_exchange, { arguments: arguments }) do
94
+ Philotic.logger.info "Added binding to queue. queue:#{q.name} binding:#{arguments}"
95
+ if arguments_index >= bindings.size - 1
96
+ Philotic.logger.info "Finished adding bindings to queue. queue:#{q.name}"
97
+ block.call(q) if block
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ def self.logger
110
+ @@logger ||= init_logger
111
+ end
112
+
113
+ def self.init_logger
114
+ Logger.new(STDOUT)
115
+ end
116
+
117
+ def self.on_publish_event(&block)
118
+ @@log_event_handler = block
119
+ end
120
+
121
+ def self.log_event_published(severity, metadata, payload, message)
122
+ if @@log_event_handler
123
+ @@log_event_handler.call(severity, metadata, payload, message)
124
+ else
125
+ logger.send(severity, "#{message}; message_metadata:#{metadata}, payload:#{payload.to_json}")
126
+ end
127
+ end
128
+
129
+ def self.connected?
130
+ Philotic::Connection.connected?
131
+ end
132
+
133
+ def self.connect! &block
134
+ Philotic::Connection.connect! &block
135
+ end
136
+ end
137
+
138
+ require 'philotic/version'
139
+ require 'philotic/connection'
140
+ require 'philotic/config'
141
+ require 'philotic/routable'
142
+ require 'philotic/event'
143
+ require 'philotic/publisher'
144
+ require 'philotic/subscriber'