vayacondios-client 0.0.3
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.
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'configliere'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
require 'gorillib/builder'
|
6
|
+
require 'gorillib/configurable'
|
7
|
+
require 'gorillib/enumerable/sum'
|
8
|
+
require 'gorillib/exception/raisers'
|
9
|
+
require 'gorillib/hash/deep_compact'
|
10
|
+
require 'gorillib/hash/deep_merge'
|
11
|
+
require 'gorillib/hash/keys'
|
12
|
+
require 'gorillib/logger/log'
|
13
|
+
require 'gorillib/metaprogramming/class_attribute'
|
14
|
+
require 'gorillib/object/blank'
|
15
|
+
require 'gorillib/string/constantize'
|
16
|
+
require 'gorillib/string/inflections'
|
17
|
+
|
18
|
+
require 'vayacondios/client/http_client'
|
19
|
+
require 'vayacondios/client/notifier'
|
20
|
+
require 'vayacondios/client/configliere'
|
21
|
+
|
22
|
+
|
23
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Vayacondios
|
2
|
+
module Configliere
|
3
|
+
|
4
|
+
def load_from_vayacondios(organization, id, options = {})
|
5
|
+
options.symbolize_keys!.deep_merge!(organization: organization)
|
6
|
+
|
7
|
+
client = ::Vayacondios::HttpClient.receive(options.deep_compact!)
|
8
|
+
id = [id, options[:env]].compact.join('.')
|
9
|
+
|
10
|
+
begin
|
11
|
+
new_data = client.fetch(:config, id)
|
12
|
+
rescue ::Vayacondios::HttpClient::Error
|
13
|
+
warn "Unable to load vayacondios config '#{id}' for #{organization} at: #{client.host}:#{client.port}"
|
14
|
+
new_data = {}
|
15
|
+
end
|
16
|
+
deep_merge! new_data
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def save_to_vayacondios(organization, id, options = {})
|
21
|
+
options.symbolize_keys!.deep_merge!(organization: organization)
|
22
|
+
|
23
|
+
client = ::Vayacondios::HttpClient.receive(options.deep_compact!)
|
24
|
+
id = [id, options[:env]].compact.join('.')
|
25
|
+
|
26
|
+
begin
|
27
|
+
client.insert(self.to_hash, :config, id)
|
28
|
+
rescue ::Vayacondios::HttpClient::Error
|
29
|
+
warn "Unable to save vayacondios config '#{id}' for #{organization} at: #{client.host}:#{client.port}"
|
30
|
+
end
|
31
|
+
self
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
::Configliere::Param.class_eval do
|
37
|
+
include ::Vayacondios::Configliere
|
38
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Vayacondios
|
2
|
+
class HttpClient
|
3
|
+
include Gorillib::Builder
|
4
|
+
|
5
|
+
field :host, String, :default => 'localhost'
|
6
|
+
field :port, Integer, :default => 8000
|
7
|
+
field :organization, String, :default => 'infochimps'
|
8
|
+
|
9
|
+
class Error < StandardError; end
|
10
|
+
|
11
|
+
def uri
|
12
|
+
return @uri if @uri
|
13
|
+
|
14
|
+
uri_str = "http://#{host}:#{port}/v1"
|
15
|
+
uri_str += "/#{organization}" if organization
|
16
|
+
@uri ||= URI(uri_str)
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch(type, id)
|
20
|
+
request(:get, type, id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def insert(document = {}, type = nil, id = nil)
|
24
|
+
id ||= document.delete(:_id) || document.delete('_id')
|
25
|
+
type ||= document.delete(:_type) || document.delete('_type')
|
26
|
+
|
27
|
+
request(:post, type, id, MultiJson.dump(document))
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def request(method, type, id = nil, document = nil)
|
33
|
+
path = File.join(uri.path, type.to_s, *id.to_s.split(/\W/))
|
34
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
35
|
+
|
36
|
+
params = [method.to_sym, path]
|
37
|
+
params += [document, {'Content-Type' => 'application/json'}] unless document.nil?
|
38
|
+
|
39
|
+
response = http.send *params
|
40
|
+
|
41
|
+
if Net::HTTPSuccess === response
|
42
|
+
MultiJson.load(response.body) rescue response.body
|
43
|
+
else
|
44
|
+
raise Error.new("Error (#{response.code}) while #{method.to_s == 'get' ? 'fetching' : 'inserting'} document: " + response.body)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class Vayacondios
|
2
|
+
|
3
|
+
class_attribute :notifier
|
4
|
+
|
5
|
+
class Notifier < Vayacondios
|
6
|
+
attr_accessor :client
|
7
|
+
|
8
|
+
def prepare(obj)
|
9
|
+
case
|
10
|
+
when obj.respond_to?(:to_inspectable) then obj.to_inspectable
|
11
|
+
when obj.respond_to?(:to_wire) then obj.to_wire
|
12
|
+
when obj.respond_to?(:to_hash) then obj.to_hash
|
13
|
+
else
|
14
|
+
raise ArgumentError.new("Cannot notify '#{obj.inspect}' -- require a hash-like object.")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def notify(topic, cargo = {})
|
19
|
+
NoMethodError.unimplemented_method(self)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class LogNotifier < Notifier
|
24
|
+
|
25
|
+
def initialize(options = {})
|
26
|
+
@client = options[:log] || Log
|
27
|
+
end
|
28
|
+
|
29
|
+
def notify(topic, cargo = {})
|
30
|
+
prepped = prepare(cargo)
|
31
|
+
level = prepped.delete(:level) || :info
|
32
|
+
message = "Notification: #{topic.inspect}."
|
33
|
+
message += " Reason: #{prepped.delete(:reason)}." if prepped[:reason]
|
34
|
+
message += " Cargo: #{prepped.inspect}"
|
35
|
+
client.send(level, message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class HttpNotifier < Notifier
|
40
|
+
|
41
|
+
def initialize(options = {})
|
42
|
+
@client = Vayacondios::HttpClient.receive(options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def notify(topic, cargo = {})
|
46
|
+
prepped = prepare(cargo)
|
47
|
+
client.insert(prepped, :event, topic)
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class NotifierFactory
|
53
|
+
def self.receive(attrs = {})
|
54
|
+
type = attrs.delete(:type)
|
55
|
+
case type
|
56
|
+
when 'http' then HttpNotifier.new(attrs)
|
57
|
+
when 'log' then LogNotifier.new(attrs)
|
58
|
+
else
|
59
|
+
raise ArgumentError, "<#{type}> is not a valid build option"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.default_notifier() NotifierFactory.receive(type: 'http') ; end
|
65
|
+
|
66
|
+
module Notifications
|
67
|
+
extend Gorillib::Concern
|
68
|
+
include Gorillib::Configurable
|
69
|
+
|
70
|
+
def notify(topic, cargo = {})
|
71
|
+
notifier.notify(topic, cargo)
|
72
|
+
end
|
73
|
+
|
74
|
+
included do
|
75
|
+
class_eval do
|
76
|
+
config(:notifier, Vayacondios::NotifierFactory, default: Vayacondios.default_notifier)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
extend Notifications
|
83
|
+
self.notifier = default_notifier
|
84
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gorillib/builder'
|
3
|
+
require 'configliere'
|
4
|
+
|
5
|
+
require_relative '../../configurable/lib/gorillib_configurable_model'
|
6
|
+
require 'vayacondios/notifier'
|
7
|
+
|
8
|
+
class FakeModel
|
9
|
+
include Vayacondios::Notifications
|
10
|
+
end
|
11
|
+
|
12
|
+
describe FakeModel do
|
13
|
+
context 'including', Vayacondios::Notifications do
|
14
|
+
|
15
|
+
it 'defines an instance method notify()' do
|
16
|
+
subject.should respond_to(:notify)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'adds a configurable attribute :notifier with default' do
|
20
|
+
subject.notifier.should be_instance_of(Vayacondios.default_notifier.class)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe Vayacondios::Notifier do
|
27
|
+
|
28
|
+
shared_examples_for described_class do
|
29
|
+
it{ should respond_to(:notify) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context '.prepare' do
|
33
|
+
context 'given a Hash-like object' do
|
34
|
+
let(:hashlike) { double :hashlike, :to_hash => {} }
|
35
|
+
it 'returns a Hash' do
|
36
|
+
subject.prepare(hashlike).should be_instance_of(Hash)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'given a bad argument' do
|
41
|
+
let(:bad_arg) { 'shazam' }
|
42
|
+
it 'raises an ArgumentError' do
|
43
|
+
expect{ subject.prepare(bad_arg) }.to raise_error(ArgumentError, /Cannot notify.*#{bad_arg}.*require a hash-like object/)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe Vayacondios::HttpNotifier do
|
51
|
+
it_behaves_like Vayacondios::Notifier
|
52
|
+
|
53
|
+
its(:client){ should be_instance_of(Vayacondios::HttpClient) }
|
54
|
+
|
55
|
+
context '#notify' do
|
56
|
+
let(:test_client) { double :client }
|
57
|
+
let(:topic) { 'weeeeeeeeeee' }
|
58
|
+
let(:cargo) { Hash.new }
|
59
|
+
|
60
|
+
before do
|
61
|
+
subject.stub(:client).and_return(test_client)
|
62
|
+
subject.stub(:prepare).and_return(cargo)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'notifies its client correctly' do
|
66
|
+
test_client.should_receive(:insert).with(cargo, :event, topic)
|
67
|
+
subject.notify(topic, cargo)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe Vayacondios::LogNotifier do
|
73
|
+
it_behaves_like Vayacondios::Notifier
|
74
|
+
|
75
|
+
its(:client){ should be_instance_of(Logger) }
|
76
|
+
|
77
|
+
context '#notify' do
|
78
|
+
let(:test_client) { double :client }
|
79
|
+
let(:topic) { 'weeeeeeeeeee' }
|
80
|
+
let(:cargo) { Hash.new }
|
81
|
+
|
82
|
+
before do
|
83
|
+
subject.stub(:client).and_return(test_client)
|
84
|
+
subject.stub(:prepare).and_return(cargo)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'notifies its client correctly' do
|
88
|
+
test_client.should_receive(:info).with(/Notification.*#{topic}/)
|
89
|
+
subject.notify(topic, cargo)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe Vayacondios::NotifierFactory do
|
96
|
+
context '.receive' do
|
97
|
+
context 'given :http' do
|
98
|
+
it 'builds a HttpNotifier' do
|
99
|
+
described_class.receive(type: 'http').should be_instance_of(Vayacondios::HttpNotifier)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'given :log' do
|
104
|
+
it 'builds a LogNotifier' do
|
105
|
+
described_class.receive(type: 'log').should be_instance_of(Vayacondios::LogNotifier)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'given a bad argument' do
|
110
|
+
it 'raises an ArgumentError' do
|
111
|
+
expect{ described_class.receive(type: 'bad') }.to raise_error(ArgumentError, /not a valid build option/)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe Vayacondios do
|
118
|
+
|
119
|
+
it 'has a class method notify()' do
|
120
|
+
described_class.should respond_to(:notify)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vayacondios-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Philip (flip) Kromer
|
9
|
+
- Travis Dempsey
|
10
|
+
- Huston Hoburg
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-08-16 00:00:00.000000000Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: configliere
|
18
|
+
requirement: &2170425660 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.4.16
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *2170425660
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: multi_json
|
29
|
+
requirement: &2170425160 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.1'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *2170425160
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: gorillib
|
40
|
+
requirement: &2170424700 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - =
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.4.0pre
|
46
|
+
type: :runtime
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *2170424700
|
49
|
+
description: ! " \nSimple
|
50
|
+
enough to use in a shell script, performant enough to use everywhere. Why the hell
|
51
|
+
wouldn't you record that metric, ese?\n\n* Client code\n\n"
|
52
|
+
email:
|
53
|
+
executables: []
|
54
|
+
extensions: []
|
55
|
+
extra_rdoc_files: []
|
56
|
+
files:
|
57
|
+
- lib/vayacondios-client.rb
|
58
|
+
- lib/vayacondios/client/configliere.rb
|
59
|
+
- lib/vayacondios/client/http_client.rb
|
60
|
+
- lib/vayacondios/client/notifier.rb
|
61
|
+
- spec/client/notifier_spec.rb
|
62
|
+
homepage: https://github.com/infochimps-labs/vayacondios
|
63
|
+
licenses: []
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
hash: 546804456992730553
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
hash: 546804456992730553
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 1.8.15
|
89
|
+
signing_key:
|
90
|
+
specification_version: 3
|
91
|
+
summary: Data goes in. The right thing happens
|
92
|
+
test_files:
|
93
|
+
- spec/client/notifier_spec.rb
|
94
|
+
has_rdoc:
|