vayacondios-client 0.2.11 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.gitignore +64 -0
  2. data/.travis.yml +13 -0
  3. data/CHANGELOG.md +0 -0
  4. data/Gemfile +21 -0
  5. data/LICENSE.md +95 -0
  6. data/Procfile +2 -0
  7. data/README.md +734 -0
  8. data/Rakefile +93 -0
  9. data/bin/vcd +10 -0
  10. data/config/database.yml +6 -0
  11. data/config/spec.example.yml +18 -0
  12. data/config/vayacondios.example.yml +15 -0
  13. data/examples/configuration.rb +56 -0
  14. data/examples/event_stream.rb +19 -0
  15. data/examples/simple.rb +61 -0
  16. data/features/event.feature +319 -0
  17. data/features/events.feature +208 -0
  18. data/features/stash.feature +840 -0
  19. data/features/stashes.feature +492 -0
  20. data/features/step_definitions/stash_steps.rb +113 -0
  21. data/features/stream.feature +30 -0
  22. data/features/support/em.rb +14 -0
  23. data/features/support/env.rb +13 -0
  24. data/lib/vayacondios/client/cli.rb +456 -0
  25. data/lib/vayacondios/client/configuration.rb +13 -0
  26. data/lib/vayacondios/client/connection.rb +39 -0
  27. data/lib/vayacondios/client/http_client.rb +6 -42
  28. data/lib/vayacondios/client/http_methods.rb +85 -0
  29. data/lib/vayacondios/client.rb +21 -0
  30. data/lib/vayacondios/configuration.rb +63 -0
  31. data/lib/vayacondios-client.rb +16 -17
  32. data/lib/vayacondios.rb +22 -0
  33. data/pom.xml +168 -0
  34. data/spec/client/cli_spec.rb +283 -0
  35. data/spec/client/configuration_spec.rb +11 -0
  36. data/spec/client/http_client_spec.rb +150 -0
  37. data/spec/configuration_spec.rb +41 -0
  38. data/spec/spec_helper.rb +27 -0
  39. data/spec/support/database_helper.rb +42 -0
  40. data/spec/support/log_helper.rb +19 -0
  41. data/spec/support/shared_context_for_events.rb +22 -0
  42. data/spec/support/shared_context_for_stashes.rb +24 -0
  43. data/spec/support/shared_examples_for_handlers.rb +32 -0
  44. data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
  45. data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
  46. data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +500 -0
  47. data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
  48. data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
  49. data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
  50. data/vayacondios-client.gemspec +25 -0
  51. metadata +96 -60
  52. checksums.yaml +0 -15
  53. data/lib/vayacondios/client/config.rb +0 -7
  54. data/lib/vayacondios/client/configliere.rb +0 -38
  55. data/lib/vayacondios/client/cube_client.rb +0 -39
  56. data/lib/vayacondios/client/itemset.rb +0 -130
  57. data/lib/vayacondios/client/legacy_switch.rb +0 -43
  58. data/lib/vayacondios/client/notifier.rb +0 -123
  59. data/lib/vayacondios/client/zabbix_client.rb +0 -148
  60. data/spec/client/itemset_legacy_spec.rb +0 -55
  61. data/spec/client/itemset_spec.rb +0 -60
  62. data/spec/client/notifier_spec.rb +0 -120
@@ -0,0 +1,456 @@
1
+ require 'vayacondios/client'
2
+
3
+ module Vayacondios::Client
4
+
5
+ # Implements a program `vcd` which makes it easy to interact with
6
+ # Vayacondios from the command-line or from scripts.
7
+ #
8
+ # It makes it easy to use files, pipes, or the command-line itself
9
+ # to pass data to Vayacondios.
10
+ #
11
+ # The 'document' and the 'query' are String inputs passed on the
12
+ # command line. These String inputs are combined with String inputs
13
+ # read from files named via command-line options or from STDIN to
14
+ # create an array of "inputs" for each command to operate on.
15
+ #
16
+ # @attr [Vayacondios::HttpClient] client the client used to communicate with the server
17
+ # @attr [String] topic the topic of the current request
18
+ # @attr [String] id the ID of the current request
19
+ # @attr [String] document a document read from a file or passed from the command-line
20
+ # @attr [String] query a query read from a file or passed from the command-line
21
+ class CLI
22
+
23
+ Error = Class.new(StandardError)
24
+
25
+ attr_accessor :client, :topic, :id, :document, :query
26
+
27
+ def usage
28
+ <<-USAGE.gsub(/^ {8}/, '').chomp
29
+ usage:
30
+ vcd [ --param=val|--param|-p val|-p ] announce TOPIC [DOCUMENT] [ID]
31
+ vcd [ --param=val|--param|-p val|-p ] get|set|set!|delete TOPIC ID [DOCUMENT]
32
+ vcd [ --param=val|--param|-p val|-p ] events TOPIC QUERY
33
+ vcd [ --param=val|--param|-p val|-p ] stashes QUERY
34
+ vcd [ --param=val|--param|-p val|-p ] set_many|set_many! QUERY_AND_UPDATE
35
+ vcd [ --param=val|--param|-p val|-p ] delete_many QUERY
36
+ USAGE
37
+ end
38
+
39
+ def description
40
+ <<-DESCRIPTION.gsub(/^ {8}/, '').chomp
41
+ A command-line Vayacondios client which reads/writes events and
42
+ configuration to/from a Vayacondios server over HTTP.
43
+
44
+ Announce an event like a successful build of your `foo` project on the
45
+ `foo.build` topic.
46
+
47
+ $ vcd announce foo.build '{"version": "1.2.3", "status": "success", "time": 27.56}'
48
+
49
+ You can also announce multiple events at once, perhaps of all your
50
+ projects on the `builds` topic.
51
+
52
+ $ cat build_events.json
53
+ {"project": "foo", "version": "1.2.3", "status": "success", "time": 27.56}
54
+ {"project": "bar", "version": "0.1.8", "status": "success", "time": 5.22}
55
+ ...
56
+ $ vcd announce builds --file=build_events.json
57
+
58
+ This works in pipelines too
59
+
60
+ $ cat build_events.json | vcd announce builds
61
+
62
+ Events are assigned their own unique ID unless a third ID argument is
63
+ provided.
64
+
65
+ Events can set their own topics if the contain a `_topic` key and
66
+ their own IDs if they contain an `_id` key. These fields can
67
+ themselves be customized, see the --topic_field and --id_field
68
+ options.
69
+
70
+ Stash a configuration value (try the `set!` if you want to
71
+ completely overwrite the old value with the new instead of merging,
72
+ which is the default behavior):
73
+
74
+ $ vcd set foo admin '{"name": "Bob Jones", "email": "bob@example.com"}'
75
+
76
+ Retrieve it again
77
+
78
+ $ vcd get foo admin
79
+ {"name": "Bob Jones", "email": "bob@example.com"}
80
+
81
+ Or delete it
82
+
83
+ $ vcd delete foo admin
84
+
85
+ Getting, setting, or deleting multiple values works the same way as
86
+ for announcing events: either from a file or over STDIN. Individual
87
+ records can also set their topic and ID just like events.
88
+
89
+ You can change the Vayacondios host, port, or organization at runtime
90
+
91
+ $ vcd announce --host=vcd.example.com --organization=myorg foo.build '{"version": "1.2.3", "status": "success", "time": 27.56}'
92
+
93
+ As well as through YAML configuration files at
94
+
95
+ /etc/vayacondios/vayacondios.yml
96
+ $PWD/config/vayacondios.yml
97
+ DESCRIPTION
98
+ end
99
+
100
+ # Returns the cmdline used for the `vcd` program.
101
+ #
102
+ # @return [Configliere::Param]
103
+ def cmdline
104
+ return @cmdline if @cmdline
105
+ c = Configliere::Param.new.use :commandline
106
+ usg = self.usage
107
+ c.define_singleton_method(:usage){ usg }
108
+ c.description = self.description
109
+
110
+ c.define :host, flag: 'h', description: "Host for Vayacondios server"
111
+ c.define :port, flag: 'p', type: Integer, description: "Port for Vayacondios server"
112
+ c.define :organization, flag: 'o', default: 'vcd', description: "Organization to write data for"
113
+ c.define :topic_field, default: '_topic', description: "Field used to dynamically determine the topic of a record"
114
+ c.define :id_field, default: '_id', description: "Field used to dynamically determine the ID of a record"
115
+ c.define :file, flag: 'f', description: "Read input from file"
116
+ c.define :log_file, description: "Path to log file (defaut: STDOUT)"
117
+ c.define :log_level, default: 'INFO', description: "Log level"
118
+ c.define :pretty, flag: 'p', type: :boolean, default: false, description: "Pretty-print output"
119
+ c.define :dry_run, type: :boolean, default: false, description: "Don't perform any actual requests"
120
+ @cmdline = c
121
+ end
122
+
123
+ # Run a new instance of the `vcd` program.
124
+ #
125
+ # Instantiates a new instance of CLI and takes it through its
126
+ # lifecycle.
127
+ #
128
+ # @raise [SystemExit] when execution stops either because requests are complete or a fatal error has occured
129
+ def self.run
130
+ cli = new
131
+ begin
132
+ cli.boot
133
+ cli.run
134
+ rescue Error => e
135
+ $stderr.puts e.message
136
+ exit(1)
137
+ end
138
+ end
139
+
140
+ def boot
141
+ cmdline.resolve!
142
+ self.client = HttpClient.new(cmdline)
143
+ log.debug "Created client with settings: #{cmdline}"
144
+ end
145
+
146
+ # Run the desired command.
147
+ #
148
+ # @raise [Error] if the desired command is unknown
149
+ def run
150
+ command = cmdline.rest.shift
151
+ return cmdline.dump_help if command.nil?
152
+ if available_commands.include? command
153
+ send command
154
+ else
155
+ raise Error.new "Unknown command: <#{command}>. Must be one of #{available_commands.inspect}"
156
+ end
157
+ end
158
+
159
+ #
160
+ # == Commands ==
161
+ #
162
+
163
+ def available_commands
164
+ %w[ announce events clear_events get get_many set set! unset unset_many ]
165
+ end
166
+
167
+ # Announce one or many events.
168
+ #
169
+ # Will read the topic as the first argument, the document as the
170
+ # second, and the ID as the third.
171
+ #
172
+ # Will iterate over each input and announce it as an event. It
173
+ # will attempt to find a topic and ID within each event and will
174
+ # fall back to using its own as a default.
175
+ #
176
+ # @raise [Error] if no topic was given
177
+ def announce
178
+ self.topic = cmdline.rest.shift or raise Error.new('Must provide a topic when announcing an event')
179
+ self.document = cmdline.rest.shift
180
+ self.id = cmdline.rest.shift
181
+ raise Error.new("Must provide an event to announce via the second command-line argument, the --file argument, or STDIN.") unless input?
182
+ inputs do |event|
183
+ handle_response client.announce(topic_for(event), event, id_for(event))
184
+ end
185
+ end
186
+
187
+ # Search for events.
188
+ #
189
+ # Will read the topic as the first argument and the query as the
190
+ # second.
191
+ #
192
+ # For each input, will send it as a query. Will attempt to find a
193
+ # topic in the query itself and will fall back to using its own as
194
+ # a default.
195
+ #
196
+ # Results are printed out one per-line.
197
+ #
198
+ # @raise [Error] if no topic was given
199
+ def events
200
+ self.topic = cmdline.rest.shift or raise Error.new("Must provide a topic when searching for events")
201
+ self.query = cmdline.rest.shift || '{}'
202
+ inputs do |query|
203
+ handle_response client.events(topic_for(query), query)
204
+ end
205
+ end
206
+
207
+ def clear_events
208
+ self.topic = cmdline.rest.shift or raise Error.new("Must provide a topic when deleting events")
209
+ self.query = cmdline.rest.shift || '{}'
210
+ inputs do |query|
211
+ handle_response client.clear_events(topic_for(query), query)
212
+ end
213
+ end
214
+ # Get a single stashed value.
215
+ #
216
+ # Will read the topic as the first argument as the ID as the
217
+ # second.
218
+ #
219
+ # For each input, will use it to get a stash. Will attempt to
220
+ # find a topic and ID in the input and will fall back to using its
221
+ # own as a default.
222
+ #
223
+ # @raise [Error] when no topic was given
224
+ def get
225
+ self.topic = cmdline.rest.shift or raise Error.new('Must provide a topic when getting a stash')
226
+ self.id = cmdline.rest.shift
227
+ if input?
228
+ inputs do |req|
229
+ handle_response client.get(topic_for(req), id_for(req))
230
+ end
231
+ else
232
+ handle_response client.get(topic, id)
233
+ end
234
+ end
235
+
236
+ # Search for multiple stashed values.
237
+ #
238
+ # Will read the query as the first argument.
239
+ #
240
+ # For each input will use it as a query.
241
+ def get_many
242
+ self.query = (cmdline.rest.shift || '{}')
243
+ inputs do |query|
244
+ handle_response client.get_many(query)
245
+ end
246
+ end
247
+
248
+ # Set a value by merging it into a (potentially) existing value.
249
+ #
250
+ # Will read the topic as the first argument, ID as the second, and
251
+ # document as the third.
252
+ #
253
+ # For each input, will merge that input. Will attempt to read a
254
+ # topic and ID for each input and will fall back to its own as a
255
+ # default.
256
+ #
257
+ # @raise [Error] if no topic was given
258
+ def set
259
+ self.topic = cmdline.rest.shift or raise Error.new('Must provide a topic when setting a stash')
260
+ self.document = cmdline.rest.shift
261
+ self.id = cmdline.rest.shift
262
+ raise Error.new("Must provide a document to stash via the third command-line argument, the --file argument, or STDIN.") unless input?
263
+ inputs do |doc|
264
+ handle_response client.set(topic_for(doc), id_for(doc), doc)
265
+ end
266
+ end
267
+
268
+ # Set a value by overwriting a (potentially) existing value.
269
+ #
270
+ # Will read the topic as the first argument, ID as the second, and
271
+ # document as the third.
272
+ #
273
+ # For each input, will write that input. Will attempt to read a
274
+ # topic and ID for each input and will fall back to its own as a
275
+ # default.
276
+ #
277
+ # @raise [Error] if no topic was given
278
+ def set!
279
+ self.topic = cmdline.rest.shift or raise Error.new('Must provide a topic when setting a stash')
280
+ self.document = cmdline.rest.shift
281
+ self.id = cmdline.rest.shift
282
+ raise Error.new("Must provide a document to stash via the third command-line argument, the --file argument, or STDIN.") unless input?
283
+ inputs do |doc|
284
+ handle_response client.set!(topic_for(doc), id_for(doc), doc)
285
+ end
286
+ end
287
+
288
+ # Delete a stashed value.
289
+ #
290
+ # Will read the topic as the first argument and ID as the second.
291
+ #
292
+ # For each input, will delete that input. Will attempt to read a
293
+ # topic and ID for each input and will fall back to its own as a
294
+ # default.
295
+ #
296
+ # @raise [Error] if no topic was given
297
+ def unset
298
+ self.topic = cmdline.rest.shift or raise Error.new('Must provide a topic when deleting a stash')
299
+ self.id = cmdline.rest.shift
300
+ if input?
301
+ inputs do |req|
302
+ handle_response client.unset(topic_for(req), id_for(req))
303
+ end
304
+ else
305
+ handle_response client.unset(topic, id)
306
+ end
307
+ end
308
+
309
+ # Delete many stashes that match some criteria.
310
+ #
311
+ # Each input should be a query Hash.
312
+ #
313
+ # @raise [Error] if no input was given
314
+ def unset_many
315
+ self.document = cmdline.rest.shift
316
+ raise Error.new("Must provide a query via the second command-line argument, the --file argument, or STDIN.") unless input?
317
+ inputs do |query|
318
+ handle_response client.unset_many(query)
319
+ end
320
+ end
321
+
322
+ #
323
+ # == Inputs ==
324
+ #
325
+
326
+ # Were there any inputs?
327
+ #
328
+ # Input is either a document passed on the command-line, a file
329
+ # requested to be read from the command-line, or is imminent
330
+ # because data is queuing up on STDIN.
331
+ #
332
+ # @return [true, false]
333
+ def input?
334
+ document || cmdline.file || input_on_stdin?
335
+ end
336
+
337
+ # For each input, parse each line as a JSON record and yield it to
338
+ # the given block.
339
+ #
340
+ # First the document and/or query will be processed, then any file
341
+ # named on the command-line, then data over STDIN.
342
+ #
343
+ # @yield [input] yields each parsed line from each input
344
+ # @yieldparam [Hash,Array,String,Numeric,nil] input the input
345
+ def inputs(&block)
346
+ raw_inputs do |line|
347
+ begin
348
+ yield MultiJson.load(line)
349
+ rescue => e
350
+ log.error("#{e.class} -- #{e.message}")
351
+ $stderr.puts(e.backtrace)
352
+ end
353
+ end
354
+ end
355
+
356
+ protected
357
+
358
+ def raw_inputs(&block)
359
+ case
360
+ when document || query
361
+ [document, query].compact.each(&block)
362
+ when cmdline.file
363
+ File.open(cmdline.file).each(&block)
364
+ when input_on_stdin?
365
+ $stdin.each(&block)
366
+ end
367
+ end
368
+
369
+ # Is there data pending to be read on STDIN?
370
+ #
371
+ # @return [true, false]
372
+ def input_on_stdin?
373
+ ! $stdin.tty?
374
+ end
375
+
376
+ #
377
+ # == Routing ==
378
+ #
379
+
380
+ # Return the topic for the given document.
381
+ #
382
+ # Will read key named by #topic_field if present, otherwise the
383
+ # default topic.
384
+ #
385
+ # @param [Hash] doc
386
+ # @return [String] topic
387
+ def topic_for doc
388
+ return topic unless doc.is_a?(Hash)
389
+ doc.delete(cmdline.topic_field) || topic
390
+ end
391
+
392
+ # Return the ID for the given document.
393
+ #
394
+ # Will read key named by #id_field if present, otherwise the
395
+ # default ID.
396
+ #
397
+ # @param [Hash] doc
398
+ # @return [String] id
399
+ def id_for doc
400
+ raw_id = doc.is_a?(Hash) ? (doc.delete(cmdline.id_field) || id) : id
401
+ raw_id == '-' ? nil : raw_id
402
+ end
403
+
404
+ #
405
+ # == Output ==
406
+ #
407
+
408
+ # Handle the JSON response that returns from the Vayacondios
409
+ # server by printing it out, one response per-line.
410
+ #
411
+ # If the `pretty` option was specified then the data will be
412
+ # pretty-printed first.
413
+ #
414
+ # @param [Hash, Array, String, Numeric, nil] doc any of the core JSON types
415
+ def handle_response res
416
+ if res.success?
417
+ display MultiJson.dump(res.body, pretty: cmdline.pretty)
418
+ else
419
+ display res.body['error']
420
+ end
421
+ end
422
+
423
+ #
424
+ # == Log ==
425
+ #
426
+
427
+ def display str
428
+ puts str
429
+ end
430
+ # Where to send log output.
431
+ #
432
+ # @return [IO]
433
+ def log_output
434
+ case cmdline.log_file
435
+ when '-' then $stdout
436
+ when String then File.open(log_file)
437
+ else
438
+ $stderr
439
+ end
440
+ end
441
+
442
+ public
443
+
444
+ # The log that will be used by the `vcd` program as it runs.
445
+ #
446
+ # @return [Logger]
447
+ def log
448
+ return @log if @log
449
+ require 'logger'
450
+ @log = Logger.new(log_output)
451
+ @log.level = Logger.const_get(cmdline.log_level.upcase)
452
+ @log
453
+ end
454
+
455
+ end
456
+ end
@@ -0,0 +1,13 @@
1
+ module Vayacondios::Client
2
+ class Configuration < Vayacondios::Configuration
3
+ def defaults
4
+ {
5
+ host: Vayacondios::DEFAULT_SERVER_ADDRESS,
6
+ port: Vayacondios::DEFAULT_SERVER_PORT,
7
+ adapter: :net_http,
8
+ }
9
+ end
10
+ end
11
+
12
+ ConnectionOpts = Configuration.new unless defined? ConnectionOpts
13
+ end
@@ -0,0 +1,39 @@
1
+ module Vayacondios::Client
2
+ module Connection
3
+
4
+ def self.base_uri options
5
+ host = options[:host] || ConnectionOpts[:host]
6
+ port = options[:port] || ConnectionOpts[:port]
7
+ "http://#{host}:#{port}/#{Vayacondios::API_VERSION}"
8
+ end
9
+
10
+ def self.factory(options = {})
11
+ Faraday.new(base_uri options) do |setup|
12
+ setup.request :json
13
+ setup.adapter options[:adapter] || ConnectionOpts[:adapter]
14
+ setup.response :json, content_type: /\bjson$/
15
+ if logger = options[:log] || ConnectionOpts[:log]
16
+ setup.response :logger, logger
17
+ end
18
+ end
19
+ end
20
+
21
+ def organization
22
+ 'vcd'
23
+ end
24
+
25
+ def url(handler, topic = nil, id = nil)
26
+ segments = [organization, handler, topic, id].compact.map(&:to_s)
27
+ File.join(*segments)
28
+ end
29
+
30
+ def configure_connection options
31
+ @connection = Connection.factory(options)
32
+ end
33
+
34
+ def http_connection
35
+ @connection ||= Connection.factory
36
+ end
37
+
38
+ end
39
+ end
@@ -1,49 +1,13 @@
1
- class Vayacondios
1
+ module Vayacondios::Client
2
2
  class HttpClient
3
- include Gorillib::Model
3
+ include HttpRead, HttpWrite, HttpAdmin
4
4
 
5
- field :host, String, :default => 'localhost'
6
- field :port, String, :default => '8000'
7
- field :organization, String, :default => 'infochimps'
8
-
9
- class Error < StandardError; end
5
+ attr_reader :organization
10
6
 
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))
7
+ def initialize(options = {})
8
+ @organization = options.delete(:organization)
9
+ configure_connection(options) unless options.empty?
28
10
  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
11
 
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
12
  end
48
13
  end
49
-
@@ -0,0 +1,85 @@
1
+ module Vayacondios::Client
2
+ module HttpRead
3
+ include Connection
4
+
5
+ # Retrieve one stash
6
+ def get(topic, id = nil)
7
+ http_connection.get url('stash', topic, id)
8
+ end
9
+
10
+ # Search stashes
11
+ def get_many(query = {})
12
+ http_connection.get url('stashes') do |req|
13
+ req.body = query
14
+ end
15
+ end
16
+
17
+ # Search events
18
+ def events(topic, query = {})
19
+ http_connection.get url('events', topic) do |req|
20
+ req.body = query
21
+ end
22
+ end
23
+
24
+ # Stream events
25
+ # only works with net/http
26
+ def stream(topic, query = {}, &on_event)
27
+ uri = http_connection.url_prefix
28
+ Net::HTTP.start(uri.host, uri.port) do |http|
29
+ path = File.join(uri.request_uri, url('stream', topic))
30
+ request = Net::HTTP::Get.new(path)
31
+ http.request(request) do |response|
32
+ buffer = ''
33
+ response.read_body do |chunk|
34
+ buffer += chunk
35
+ while line = buffer.slice!(/^[^\n].*\n/)
36
+ on_event.call MultiJson.load(line.strip)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ module HttpWrite
45
+ include Connection
46
+
47
+ # Create a stash
48
+ def set(topic, id = nil, stash = {})
49
+ http_connection.post url('stash', topic, id) do |req|
50
+ req.body = stash
51
+ end
52
+ end
53
+ alias :set! :set
54
+
55
+ # Create an event
56
+ def announce(topic, event = {}, id = nil)
57
+ http_connection.post url('event', topic, id) do |req|
58
+ req.body = event
59
+ end
60
+ end
61
+ end
62
+
63
+ module HttpAdmin
64
+ include Connection
65
+
66
+ # Delete one stash
67
+ def unset(topic, id = nil)
68
+ http_connection.delete url('stash', topic, id)
69
+ end
70
+
71
+ # Delete stashes by search
72
+ def unset_many(query = {})
73
+ http_connection.delete url('stashes') do |req|
74
+ req.body = query
75
+ end
76
+ end
77
+
78
+ # Delete all events by topic and query
79
+ def clear_events(topic, query = {})
80
+ http_connection.delete url('events', topic) do |req|
81
+ req.body = query
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,21 @@
1
+ require 'configliere'
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+ require 'gorillib'
5
+ require 'gorillib/metaprogramming/class_attribute'
6
+ require 'gorillib/string/inflections'
7
+ require 'logger'
8
+ require 'multi_json'
9
+
10
+ require 'vayacondios'
11
+ require 'vayacondios/configuration'
12
+ require 'vayacondios/client/configuration'
13
+ require 'vayacondios/client/connection'
14
+ require 'vayacondios/client/http_methods'
15
+ require 'vayacondios/client/http_client'
16
+
17
+ module Vayacondios
18
+ module Client
19
+
20
+ end
21
+ end