vayacondios-client 0.2.11 → 0.3.0
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.
- data/.gitignore +64 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +21 -0
- data/LICENSE.md +95 -0
- data/Procfile +2 -0
- data/README.md +734 -0
- data/Rakefile +93 -0
- data/bin/vcd +10 -0
- data/config/database.yml +6 -0
- data/config/spec.example.yml +18 -0
- data/config/vayacondios.example.yml +15 -0
- data/examples/configuration.rb +56 -0
- data/examples/event_stream.rb +19 -0
- data/examples/simple.rb +61 -0
- data/features/event.feature +319 -0
- data/features/events.feature +208 -0
- data/features/stash.feature +840 -0
- data/features/stashes.feature +492 -0
- data/features/step_definitions/stash_steps.rb +113 -0
- data/features/stream.feature +30 -0
- data/features/support/em.rb +14 -0
- data/features/support/env.rb +13 -0
- data/lib/vayacondios/client/cli.rb +456 -0
- data/lib/vayacondios/client/configuration.rb +13 -0
- data/lib/vayacondios/client/connection.rb +39 -0
- data/lib/vayacondios/client/http_client.rb +6 -42
- data/lib/vayacondios/client/http_methods.rb +85 -0
- data/lib/vayacondios/client.rb +21 -0
- data/lib/vayacondios/configuration.rb +63 -0
- data/lib/vayacondios-client.rb +16 -17
- data/lib/vayacondios.rb +22 -0
- data/pom.xml +168 -0
- data/spec/client/cli_spec.rb +283 -0
- data/spec/client/configuration_spec.rb +11 -0
- data/spec/client/http_client_spec.rb +150 -0
- data/spec/configuration_spec.rb +41 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/database_helper.rb +42 -0
- data/spec/support/log_helper.rb +19 -0
- data/spec/support/shared_context_for_events.rb +22 -0
- data/spec/support/shared_context_for_stashes.rb +24 -0
- data/spec/support/shared_examples_for_handlers.rb +32 -0
- data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
- data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
- data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +500 -0
- data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
- data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
- data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
- data/vayacondios-client.gemspec +25 -0
- metadata +96 -60
- checksums.yaml +0 -15
- data/lib/vayacondios/client/config.rb +0 -7
- data/lib/vayacondios/client/configliere.rb +0 -38
- data/lib/vayacondios/client/cube_client.rb +0 -39
- data/lib/vayacondios/client/itemset.rb +0 -130
- data/lib/vayacondios/client/legacy_switch.rb +0 -43
- data/lib/vayacondios/client/notifier.rb +0 -123
- data/lib/vayacondios/client/zabbix_client.rb +0 -148
- data/spec/client/itemset_legacy_spec.rb +0 -55
- data/spec/client/itemset_spec.rb +0 -60
- data/spec/client/notifier_spec.rb +0 -120
@@ -1,130 +0,0 @@
|
|
1
|
-
require 'gorillib/logger/log'
|
2
|
-
require 'net/http'
|
3
|
-
require 'multi_json'
|
4
|
-
require_relative 'config'
|
5
|
-
require_relative 'legacy_switch'
|
6
|
-
|
7
|
-
class Vayacondios
|
8
|
-
class Client
|
9
|
-
class ItemSet
|
10
|
-
def initialize host, port, organization=nil, topic=nil, id=nil
|
11
|
-
@host = host
|
12
|
-
@port = port
|
13
|
-
@organization = organization
|
14
|
-
@topic = topic
|
15
|
-
@id = id
|
16
|
-
end
|
17
|
-
|
18
|
-
def fetch organization=nil, topic=nil, id=nil
|
19
|
-
resp = execute_request(_req(:fetch, nil, organization, topic, id)) and
|
20
|
-
Vayacondios.legacy_switch.extract_response(resp)
|
21
|
-
end
|
22
|
-
|
23
|
-
def update ary, organization=nil, topic=nil, id=nil
|
24
|
-
execute_request(_req(:update, ary, organization, topic, id))
|
25
|
-
end
|
26
|
-
|
27
|
-
def create ary, organization=nil, topic=nil, id=nil
|
28
|
-
execute_request(_req(:create, ary, organization, topic, id))
|
29
|
-
end
|
30
|
-
|
31
|
-
def remove ary, organization=nil, topic=nil, id=nil
|
32
|
-
execute_request(_req(:remove, ary, organization, topic, id))
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def execute_request req
|
38
|
-
begin
|
39
|
-
resp = Net::HTTP.start(@host, @port) do |http|
|
40
|
-
http.request(req)
|
41
|
-
end.body
|
42
|
-
result = MultiJson.decode(resp) unless resp.nil? or resp.empty?
|
43
|
-
(result.respond_to?(:has_key?) and result.has_key? "error") ? nil : result
|
44
|
-
rescue StandardError => ex
|
45
|
-
Log.warn("problem contacting vayacondios: #{ex.message}")
|
46
|
-
Log.debug(ex.backtrace.join("\n"))
|
47
|
-
nil
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def path organization, topic, id
|
52
|
-
if ((the_organization = (organization || @organization)).nil? ||
|
53
|
-
(the_topic = (topic || @topic )).nil? ||
|
54
|
-
(the_id = (id || @id )).nil?)
|
55
|
-
raise ArgumentError.new("must provide organization, topic, and id!")
|
56
|
-
end
|
57
|
-
|
58
|
-
['/v1', the_organization, 'itemset', the_topic, the_id].join("/")
|
59
|
-
end
|
60
|
-
|
61
|
-
# This is the only private method that is tested.
|
62
|
-
def _req type, ary=nil, organization=nil, topic=nil, id=nil
|
63
|
-
|
64
|
-
the_path = path(organization, topic, id)
|
65
|
-
headers = {"content-type" => "application/json"}
|
66
|
-
headers.merge!("x-method" => "PATCH") if type == :update
|
67
|
-
|
68
|
-
case type
|
69
|
-
when :fetch then Net::HTTP::Get
|
70
|
-
when :create then Net::HTTP::Put
|
71
|
-
when :update then Net::HTTP::Put
|
72
|
-
when :remove then Net::HTTP::Delete
|
73
|
-
else raise ArgumentError.new("invalid type: #{type}")
|
74
|
-
end.new(the_path, headers).tap do |req|
|
75
|
-
unless type == :fetch
|
76
|
-
req.body =
|
77
|
-
MultiJson.encode(Vayacondios.legacy_switch.wrap_contents(ary))
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Subclasses should implement the remove_items(arr) and
|
84
|
-
# add_items(arr) methods, both of which will be called with arrays
|
85
|
-
# when the items in an itemset change. The run method polls the
|
86
|
-
# provided itemset at a specified interval and calls these methods
|
87
|
-
# appropriately.
|
88
|
-
class ItemSetListener
|
89
|
-
POLL_WAIT_SEC=2
|
90
|
-
|
91
|
-
def initialize itemset, poll_wait_sec = POLL_WAIT_SEC
|
92
|
-
@itemset = itemset
|
93
|
-
@items = []
|
94
|
-
@poll_wait_sec = poll_wait_sec
|
95
|
-
end
|
96
|
-
|
97
|
-
def run
|
98
|
-
setup
|
99
|
-
loop do
|
100
|
-
new_items = @itemset.fetch || []
|
101
|
-
|
102
|
-
Log.debug "currently configured: #{@items.inspect}"
|
103
|
-
Log.debug "new items: #{new_items.inspect}"
|
104
|
-
|
105
|
-
add_items(new_items - @items)
|
106
|
-
remove_items(@items - new_items)
|
107
|
-
|
108
|
-
@items = new_items
|
109
|
-
|
110
|
-
sleep @poll_wait_sec
|
111
|
-
end
|
112
|
-
teardown
|
113
|
-
end
|
114
|
-
|
115
|
-
protected
|
116
|
-
|
117
|
-
def add_items
|
118
|
-
raise NoMethodError.new("class #{self.class.name} must override add_items")
|
119
|
-
end
|
120
|
-
|
121
|
-
def remove_items
|
122
|
-
raise NoMethodError.new("class #{self.class.name} must override remove_items")
|
123
|
-
end
|
124
|
-
|
125
|
-
def setup() end
|
126
|
-
def teardown() end
|
127
|
-
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'gorillib/logger/log'
|
2
|
-
|
3
|
-
class Vayacondios
|
4
|
-
# Are we operating on JSON Hashes (Vayacondios) or on JSON arrays
|
5
|
-
# (Vayacondios Legacy)? These classes determine which to use.
|
6
|
-
|
7
|
-
class StandardContentsHandler
|
8
|
-
def wrap_contents(contents) {contents: contents} end
|
9
|
-
def extract_contents(document) document['contents'] end
|
10
|
-
def extract_response(document) document['contents'] end
|
11
|
-
def proper_request(document) true end
|
12
|
-
end
|
13
|
-
|
14
|
-
class LegacyContentsHandler
|
15
|
-
def wrap_contents(contents) contents end
|
16
|
-
def extract_contents(document) document end
|
17
|
-
def extract_response(document) document end
|
18
|
-
def proper_request(document) true end
|
19
|
-
end
|
20
|
-
|
21
|
-
@@legacy_switch = nil
|
22
|
-
|
23
|
-
def self.legacy_switch
|
24
|
-
if @@legacy_switch.nil?
|
25
|
-
legacy_mode_on = Settings[:vayacondios][:legacy]
|
26
|
-
@@legacy_switch = get_legacy_switch(legacy_mode_on)
|
27
|
-
Log.info("using #{legacy_mode_on ? 'legacy' : 'standard'} mode")
|
28
|
-
end
|
29
|
-
@@legacy_switch
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.force_legacy_mode on
|
33
|
-
Log.info("forcing #{on ? 'legacy' : 'standard'} mode")
|
34
|
-
@@legacy_switch = get_legacy_switch on
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def self.get_legacy_switch on
|
40
|
-
(on ? LegacyContentsHandler : StandardContentsHandler).new
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
@@ -1,123 +0,0 @@
|
|
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 NullNotifier < Notifier
|
24
|
-
def initialize(*args) ; end
|
25
|
-
|
26
|
-
def notify topic, cargo={}
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class LogNotifier < Notifier
|
31
|
-
|
32
|
-
def initialize(options = {})
|
33
|
-
@client = options[:log] || Log
|
34
|
-
end
|
35
|
-
|
36
|
-
def notify(topic, cargo = {})
|
37
|
-
prepped = prepare(cargo)
|
38
|
-
level = prepped.delete(:level) || :info
|
39
|
-
message = "Notification: #{topic.inspect}."
|
40
|
-
message += " Reason: #{prepped.delete(:reason)}." if prepped[:reason]
|
41
|
-
message += " Cargo: #{prepped.inspect}"
|
42
|
-
client.send(level, message)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class HttpNotifier < Notifier
|
47
|
-
|
48
|
-
def initialize(options = {})
|
49
|
-
@client = Vayacondios::HttpClient.receive(options)
|
50
|
-
end
|
51
|
-
|
52
|
-
def notify(topic, cargo = {})
|
53
|
-
prepped = prepare(cargo)
|
54
|
-
client.insert(prepped, :event, topic)
|
55
|
-
nil
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class CubeNotifier < Notifier
|
60
|
-
def initialize(options={})
|
61
|
-
@client = Vayacondios::CubeClient.receive(options)
|
62
|
-
end
|
63
|
-
def notify topic, cargo={}
|
64
|
-
prepped = prepare(cargo)
|
65
|
-
client.event(topic, prepped)
|
66
|
-
nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
class ZabbixNotifier < Notifier
|
71
|
-
def initialize options={}
|
72
|
-
@client = Vayacondios::ZabbixClient.receive(options)
|
73
|
-
end
|
74
|
-
def notify(topic, cargo={})
|
75
|
-
prepped = prepare(cargo)
|
76
|
-
client.insert(topic, prepped)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
class NotifierFactory
|
81
|
-
def self.receive(attrs = {})
|
82
|
-
type = attrs[:type]
|
83
|
-
case type
|
84
|
-
when 'http' then HttpNotifier.new(attrs)
|
85
|
-
when 'cube' then CubeNotifier.new(attrs)
|
86
|
-
when 'zabbix' then ZabbixNotifier.new(attrs)
|
87
|
-
when 'log' then LogNotifier.new(attrs)
|
88
|
-
when 'none','null' then NullNotifier.new(attrs)
|
89
|
-
else
|
90
|
-
raise ArgumentError, "<#{type}> is not a valid build option"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.default_notifier(log = nil) NotifierFactory.receive(type: 'log', log: log) ; end
|
96
|
-
|
97
|
-
module Notifications
|
98
|
-
|
99
|
-
def notify(topic, cargo = {})
|
100
|
-
notifier.notify(topic, cargo)
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.included klass
|
104
|
-
if klass.ancestors.include? Gorillib::Model
|
105
|
-
klass.class_eval do
|
106
|
-
field :notifier, Vayacondios::NotifierFactory, default: Vayacondios.default_notifier, :doc => "Notifier used to notify out of band data"
|
107
|
-
|
108
|
-
def receive_notifier params
|
109
|
-
params.merge!(log: try(:log)) if params[:type] == 'log'
|
110
|
-
@notifier = Vayacondios::NotifierFactory.receive(params)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
else
|
114
|
-
klass.class_attribute :notifier
|
115
|
-
klass.notifier = Vayacondios.default_notifier try(:log)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
extend Notifications
|
122
|
-
self.notifier = default_notifier
|
123
|
-
end
|
@@ -1,148 +0,0 @@
|
|
1
|
-
require 'socket'
|
2
|
-
|
3
|
-
class Vayacondios
|
4
|
-
|
5
|
-
# Used for sending events to a Zabbix server.
|
6
|
-
#
|
7
|
-
# An 'event' from Vayacondios' perspective is an arbitrary Hash.
|
8
|
-
#
|
9
|
-
# An 'event' from Zabbix's perspective is a tuple of values:
|
10
|
-
#
|
11
|
-
# * time
|
12
|
-
# * host
|
13
|
-
# * key
|
14
|
-
# * value
|
15
|
-
#
|
16
|
-
# This client will accept a Vayacondios event and internally
|
17
|
-
# translate it into a set of Zabbix events.
|
18
|
-
#
|
19
|
-
# @example A CPU monitoring notification
|
20
|
-
#
|
21
|
-
# notify "foo-server.example.com", cpu: {
|
22
|
-
# util: {
|
23
|
-
# user: 0.20,
|
24
|
-
# idle: 0.70,
|
25
|
-
# sys: 0.10
|
26
|
-
# },
|
27
|
-
# load: 1.3
|
28
|
-
# }
|
29
|
-
#
|
30
|
-
# would get turned into the following events when written to Zabbix:
|
31
|
-
#
|
32
|
-
# @example The CPU monitoring notification translated to Zabbix events
|
33
|
-
#
|
34
|
-
# [
|
35
|
-
# { host: "foo-server.example.com", key: "cpu.util.user", value: 0.20 }
|
36
|
-
# { host: "foo-server.example.com", key: "cpu.util.idle", value: 0.70 },
|
37
|
-
# { host: "foo-server.example.com", key: "cpu.util.sys", value: 0.10 },
|
38
|
-
# { host: "foo-server.example.com", key: "cpu.load", value: 1.3 }
|
39
|
-
# ]
|
40
|
-
#
|
41
|
-
# Zabbix will interpret the time as the time it receives each event.
|
42
|
-
#
|
43
|
-
# The following links provide details on the protocol used by Zabbix
|
44
|
-
# to receive events:
|
45
|
-
#
|
46
|
-
# * https://www.zabbix.com/forum/showthread.php?t=20047&highlight=sender
|
47
|
-
# * https://gist.github.com/1170577
|
48
|
-
# * http://spin.atomicobject.com/2012/10/30/collecting-metrics-from-ruby-processes-using-zabbix-trappers/?utm_source=rubyflow&utm_medium=ao&utm_campaign=collecting-metrics-zabix
|
49
|
-
class ZabbixClient
|
50
|
-
include Gorillib::Builder
|
51
|
-
|
52
|
-
attr_accessor :socket
|
53
|
-
|
54
|
-
field :host, String, :default => 'localhost', :doc => "Host for the Zabbix server"
|
55
|
-
field :port, Integer, :default => 10051, :doc => "Port for the Zabbix server"
|
56
|
-
|
57
|
-
# Insert events to a Zabbix server.
|
58
|
-
#
|
59
|
-
# The `topic` will be used as the name of the Zabbix host to
|
60
|
-
# associate event data to.
|
61
|
-
#
|
62
|
-
# As per the documentation for the [Zabbix sender
|
63
|
-
# protocol](https://www.zabbix.com/wiki/doc/tech/proto/zabbixsenderprotocol),
|
64
|
-
# a new TCP connection will be created for each event.
|
65
|
-
#
|
66
|
-
# @param [String] topic
|
67
|
-
# @param [Hash] cargo
|
68
|
-
# Array<Hash>] text
|
69
|
-
def insert topic, cargo={}
|
70
|
-
self.socket = TCPSocket.new(host, port)
|
71
|
-
send_request(topic, cargo)
|
72
|
-
handle_response
|
73
|
-
self.socket.close
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
# :nodoc
|
79
|
-
def send_request topic, cargo
|
80
|
-
socket.write(payload(topic, cargo))
|
81
|
-
end
|
82
|
-
|
83
|
-
# :nodoc
|
84
|
-
def handle_response
|
85
|
-
header = socket.recv(5)
|
86
|
-
if header == "ZBXD\1"
|
87
|
-
data_header = socket.recv(8)
|
88
|
-
length = data_header[0,4].unpack("i")[0]
|
89
|
-
response = MultiJson.load(socket.recv(length))
|
90
|
-
puts response["info"]
|
91
|
-
else
|
92
|
-
puts "Invalid response: #{header}"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# :nodoc
|
97
|
-
def payload topic, cargo={}
|
98
|
-
body = body_for(topic, cargo)
|
99
|
-
header_for(body) + body
|
100
|
-
end
|
101
|
-
|
102
|
-
# :nodoc
|
103
|
-
def body_for topic, cargo={}
|
104
|
-
MultiJson.dump({request: "sender data", data: zabbix_events_from(topic, cargo) })
|
105
|
-
end
|
106
|
-
|
107
|
-
# :nodoc
|
108
|
-
def header_for body
|
109
|
-
length = body.bytesize
|
110
|
-
"ZBXD\1".encode("ascii") + [length].pack("i") + "\x00\x00\x00\x00"
|
111
|
-
end
|
112
|
-
|
113
|
-
# :nodoc
|
114
|
-
def zabbix_events_from topic, cargo, scope=''
|
115
|
-
events = []
|
116
|
-
case cargo
|
117
|
-
when Hash
|
118
|
-
cargo.each_pair do |key, value|
|
119
|
-
events += zabbix_events_from(topic, value, new_scope(scope, key))
|
120
|
-
end
|
121
|
-
when Array
|
122
|
-
cargo.each_with_index do |item, index|
|
123
|
-
events += zabbix_events_from(topic, item, new_scope(scope, index))
|
124
|
-
end
|
125
|
-
else
|
126
|
-
events << event_body(topic, scope, cargo)
|
127
|
-
end
|
128
|
-
events
|
129
|
-
end
|
130
|
-
|
131
|
-
# :nodoc
|
132
|
-
def new_scope(current_scope, new_scope)
|
133
|
-
[current_scope, new_scope].map(&:to_s).reject(&:empty?).join('.')
|
134
|
-
end
|
135
|
-
|
136
|
-
# :nodoc
|
137
|
-
def event_body topic, scope, cargo
|
138
|
-
value = case cargo
|
139
|
-
when Hash then cargo[:value]
|
140
|
-
when Array then cargo.first
|
141
|
-
else cargo
|
142
|
-
end
|
143
|
-
{ host: topic, key: scope, value: value }
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require_relative '../../lib/vayacondios/server/legacy_switch'
|
3
|
-
|
4
|
-
require 'multi_json'
|
5
|
-
|
6
|
-
require_relative '../../lib/vayacondios/client/itemset'
|
7
|
-
|
8
|
-
describe Vayacondios::Client::ItemSet do
|
9
|
-
context "after instantiation in legacy mode" do
|
10
|
-
itemset = Vayacondios::Client::ItemSet.new("foohost", 9999, "fooorg", "footopic", "fooid")
|
11
|
-
ary = ["foo", "bar", "baz"]
|
12
|
-
|
13
|
-
# testing internals here to avoid shimming up HTTP libraries.
|
14
|
-
|
15
|
-
it "generates a put request without a patch header when asked to create" do
|
16
|
-
Vayacondios.force_legacy_mode true
|
17
|
-
|
18
|
-
req = itemset.instance_eval{_req(:create, ary)}
|
19
|
-
|
20
|
-
req.method.should eql('PUT')
|
21
|
-
req.body.should eql(MultiJson.encode(ary))
|
22
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
23
|
-
req.each_header.to_a.should_not include(["x_method", "PATCH"])
|
24
|
-
end
|
25
|
-
|
26
|
-
it "generates a put request with a patch header when asked to update" do
|
27
|
-
Vayacondios.force_legacy_mode true
|
28
|
-
|
29
|
-
req = itemset.instance_eval{_req(:update, ary)}
|
30
|
-
|
31
|
-
req.method.should eql('PUT')
|
32
|
-
req.body.should eql(MultiJson.encode(ary))
|
33
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
34
|
-
req.each_header.to_a.should include(["x-method", "PATCH"])
|
35
|
-
end
|
36
|
-
|
37
|
-
it "generates a get request when asked to fetch" do
|
38
|
-
req = itemset.instance_eval{_req(:fetch)}
|
39
|
-
|
40
|
-
req.method.should eql('GET')
|
41
|
-
req.body.should be_nil
|
42
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
43
|
-
end
|
44
|
-
|
45
|
-
it "generates a delete request when asked to remove" do
|
46
|
-
Vayacondios.force_legacy_mode true
|
47
|
-
|
48
|
-
req = itemset.instance_eval{_req(:remove, ary)}
|
49
|
-
|
50
|
-
req.method.should eql('DELETE')
|
51
|
-
req.body.should eql(MultiJson.encode(ary))
|
52
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
data/spec/client/itemset_spec.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'multi_json'
|
4
|
-
|
5
|
-
require_relative '../../lib/vayacondios/client/itemset'
|
6
|
-
|
7
|
-
describe Vayacondios::Client::ItemSet do
|
8
|
-
context "when initialized" do
|
9
|
-
it "can be passed a host, port, organization, topic and id" do
|
10
|
-
Vayacondios::Client::ItemSet.new("foohost", 9999, "fooorg", "footopic", "fooid")
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
context "after instantiation" do
|
15
|
-
itemset = Vayacondios::Client::ItemSet.new("foohost", 9999, "fooorg", "footopic", "fooid")
|
16
|
-
ary = ["foo", "bar", "baz"]
|
17
|
-
|
18
|
-
# testing internals here to avoid shimming up HTTP libraries.
|
19
|
-
|
20
|
-
it "generates a put request without a patch header when asked to create" do
|
21
|
-
Vayacondios.force_legacy_mode false
|
22
|
-
|
23
|
-
req = itemset.instance_eval{_req(:create, ary)}
|
24
|
-
|
25
|
-
req.method.should eql('PUT')
|
26
|
-
req.body.should eql(MultiJson.encode(contents: ary))
|
27
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
28
|
-
req.each_header.to_a.should_not include(["x_method", "PATCH"])
|
29
|
-
end
|
30
|
-
|
31
|
-
it "generates a put request with a patch header when asked to update" do
|
32
|
-
Vayacondios.force_legacy_mode false
|
33
|
-
|
34
|
-
req = itemset.instance_eval{_req(:update, ary)}
|
35
|
-
|
36
|
-
req.method.should eql('PUT')
|
37
|
-
req.body.should eql(MultiJson.encode(contents: ary))
|
38
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
39
|
-
req.each_header.to_a.should include(["x-method", "PATCH"])
|
40
|
-
end
|
41
|
-
|
42
|
-
it "generates a get request when asked to fetch" do
|
43
|
-
req = itemset.instance_eval{_req(:fetch)}
|
44
|
-
|
45
|
-
req.method.should eql('GET')
|
46
|
-
req.body.should be_nil
|
47
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
48
|
-
end
|
49
|
-
|
50
|
-
it "generates a delete request when asked to remove" do
|
51
|
-
Vayacondios.force_legacy_mode false
|
52
|
-
|
53
|
-
req = itemset.instance_eval{_req(:remove, ary)}
|
54
|
-
|
55
|
-
req.method.should eql('DELETE')
|
56
|
-
req.body.should eql(MultiJson.encode(contents: ary))
|
57
|
-
req.path.should eql('/v1/fooorg/itemset/footopic/fooid')
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
require 'vayacondios-client'
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
class FakeModel
|
6
|
-
include Vayacondios::Notifications
|
7
|
-
end
|
8
|
-
|
9
|
-
describe FakeModel do
|
10
|
-
context 'including', Vayacondios::Notifications do
|
11
|
-
|
12
|
-
it 'defines an instance method notify()' do
|
13
|
-
subject.should respond_to(:notify)
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'adds a configurable attribute :notifier with default' do
|
17
|
-
subject.notifier.should be_instance_of(Vayacondios.default_notifier.class)
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe Vayacondios::Notifier do
|
24
|
-
|
25
|
-
shared_examples_for described_class do
|
26
|
-
it{ should respond_to(:notify) }
|
27
|
-
end
|
28
|
-
|
29
|
-
context '.prepare' do
|
30
|
-
context 'given a Hash-like object' do
|
31
|
-
let(:hashlike) { double :hashlike, :to_hash => {} }
|
32
|
-
it 'returns a Hash' do
|
33
|
-
subject.prepare(hashlike).should be_instance_of(Hash)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context 'given a bad argument' do
|
38
|
-
let(:bad_arg) { 'shazam' }
|
39
|
-
it 'raises an ArgumentError' do
|
40
|
-
expect{ subject.prepare(bad_arg) }.to raise_error(ArgumentError, /Cannot notify.*#{bad_arg}.*require a hash-like object/)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
describe Vayacondios::HttpNotifier do
|
48
|
-
it_behaves_like Vayacondios::Notifier
|
49
|
-
|
50
|
-
its(:client){ should be_instance_of(Vayacondios::HttpClient) }
|
51
|
-
|
52
|
-
context '#notify' do
|
53
|
-
let(:test_client) { double :client }
|
54
|
-
let(:topic) { 'weeeeeeeeeee' }
|
55
|
-
let(:cargo) { Hash.new }
|
56
|
-
|
57
|
-
before do
|
58
|
-
subject.stub(:client).and_return(test_client)
|
59
|
-
subject.stub(:prepare).and_return(cargo)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'notifies its client correctly' do
|
63
|
-
test_client.should_receive(:insert).with(cargo, :event, topic)
|
64
|
-
subject.notify(topic, cargo)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe Vayacondios::LogNotifier do
|
70
|
-
it_behaves_like Vayacondios::Notifier
|
71
|
-
|
72
|
-
its(:client){ should be_instance_of(Logger) }
|
73
|
-
|
74
|
-
context '#notify' do
|
75
|
-
let(:test_client) { double :client }
|
76
|
-
let(:topic) { 'weeeeeeeeeee' }
|
77
|
-
let(:cargo) { Hash.new }
|
78
|
-
|
79
|
-
before do
|
80
|
-
subject.stub(:client).and_return(test_client)
|
81
|
-
subject.stub(:prepare).and_return(cargo)
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'notifies its client correctly' do
|
85
|
-
test_client.should_receive(:info).with(/Notification.*#{topic}/)
|
86
|
-
subject.notify(topic, cargo)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
describe Vayacondios::NotifierFactory do
|
93
|
-
context '.receive' do
|
94
|
-
context 'given :http' do
|
95
|
-
it 'builds a HttpNotifier' do
|
96
|
-
described_class.receive(type: 'http').should be_instance_of(Vayacondios::HttpNotifier)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context 'given :log' do
|
101
|
-
it 'builds a LogNotifier' do
|
102
|
-
described_class.receive(type: 'log').should be_instance_of(Vayacondios::LogNotifier)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context 'given a bad argument' do
|
107
|
-
it 'raises an ArgumentError' do
|
108
|
-
expect{ described_class.receive(type: 'bad') }.to raise_error(ArgumentError, /not a valid build option/)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe Vayacondios do
|
115
|
-
|
116
|
-
it 'has a class method notify()' do
|
117
|
-
described_class.should respond_to(:notify)
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|