vayacondios-server 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 +3 -1
- data/.travis.yml +2 -0
- data/Gemfile +15 -9
- data/LICENSE.md +2 -6
- data/Procfile +1 -1
- data/README.md +656 -111
- data/Rakefile +89 -6
- data/bin/vcd +10 -0
- data/bin/vcd-server +8 -0
- data/config/database.yml +6 -0
- data/config/spec.example.yml +18 -0
- data/config/vayacondios.example.yml +15 -0
- data/config/vcd-server.rb +37 -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/configuration.rb +63 -0
- data/lib/vayacondios/server/api.rb +126 -0
- data/lib/vayacondios/server/api_options.rb +56 -0
- data/lib/vayacondios/server/configuration.rb +23 -0
- data/lib/vayacondios/server/driver.rb +71 -0
- data/lib/vayacondios/server/drivers/mongo.rb +126 -0
- data/lib/vayacondios/server/handlers/document_handler.rb +81 -0
- data/lib/vayacondios/server/handlers/event_handler.rb +31 -26
- data/lib/vayacondios/server/handlers/events_handler.rb +31 -0
- data/lib/vayacondios/server/handlers/stash_handler.rb +69 -0
- data/lib/vayacondios/server/handlers/stashes_handler.rb +49 -0
- data/lib/vayacondios/server/handlers/stream_handler.rb +39 -0
- data/lib/vayacondios/server/models/document.rb +87 -0
- data/lib/vayacondios/server/models/event.rb +198 -0
- data/lib/vayacondios/server/models/stash.rb +100 -0
- data/lib/vayacondios/server.rb +35 -0
- data/lib/vayacondios-server.rb +19 -13
- data/lib/vayacondios.rb +22 -0
- data/pom.xml +124 -4
- data/spec/configuration_spec.rb +41 -0
- data/spec/server/api_options_spec.rb +32 -0
- data/spec/server/api_spec.rb +279 -0
- data/spec/server/configuration_spec.rb +27 -0
- data/spec/server/drivers/mongo_spec.rb +107 -0
- data/spec/server/handlers/event_handler_spec.rb +62 -0
- data/spec/server/handlers/events_handler_spec.rb +51 -0
- data/spec/server/handlers/stash_handler_spec.rb +68 -0
- data/spec/server/handlers/stashes_handler_spec.rb +50 -0
- data/spec/server/handlers/stream_handler_spec.rb +5 -0
- data/spec/server/models/document_spec.rb +9 -0
- data/spec/server/models/event_spec.rb +185 -0
- data/spec/server/models/stash_spec.rb +95 -0
- data/spec/spec_helper.rb +23 -3
- 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 +487 -65
- 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-server.gemspec +9 -9
- metadata +127 -122
- checksums.yaml +0 -15
- data/.rspec +0 -2
- data/.yardopts +0 -10
- data/Guardfile +0 -41
- data/app/http_shim.rb +0 -71
- data/bin/vcd.sh +0 -27
- data/config/http_shim.rb +0 -43
- data/config/vayacondios.example.yaml +0 -7
- data/config/vayacondios.yaml +0 -7
- data/examples/java/ItemSetTest.java +0 -76
- data/lib/tasks/publish.rake +0 -23
- data/lib/tasks/spec.rake +0 -11
- data/lib/tasks/yard.rake +0 -2
- 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/http_client.rb +0 -49
- 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/lib/vayacondios/legacy_switch.rb +0 -43
- data/lib/vayacondios/server/errors/bad_request.rb +0 -6
- data/lib/vayacondios/server/errors/not_found.rb +0 -6
- data/lib/vayacondios/server/handlers/config_handler.rb +0 -32
- data/lib/vayacondios/server/handlers/itemset_handler.rb +0 -60
- data/lib/vayacondios/server/legacy_switch.rb +0 -43
- data/lib/vayacondios/server/model/config_document.rb +0 -89
- data/lib/vayacondios/server/model/document.rb +0 -25
- data/lib/vayacondios/server/model/event_document.rb +0 -94
- data/lib/vayacondios/server/model/itemset_document.rb +0 -126
- data/lib/vayacondios/server/rack/extract_methods.rb +0 -35
- data/lib/vayacondios/server/rack/jsonize.rb +0 -43
- data/lib/vayacondios/server/rack/params.rb +0 -50
- data/lib/vayacondios/server/rack/path.rb +0 -23
- data/lib/vayacondios/server/rack/path_validation.rb +0 -22
- data/lib/vayacondios/version.rb +0 -3
- data/lib/vayacondios-client.rb +0 -22
- data/scripts/hadoop_monitor/configurable.rb +0 -66
- data/scripts/hadoop_monitor/hadoop_attempt_scraper.rb +0 -45
- data/scripts/hadoop_monitor/hadoop_client.rb +0 -273
- data/scripts/hadoop_monitor/hadoop_monitor.rb +0 -101
- data/scripts/hadoop_monitor/hadoopable.rb +0 -65
- data/scripts/hadoop_monitor/machine_monitor.rb +0 -115
- data/scripts/s3_cataloger/buckets +0 -33
- data/scripts/s3_cataloger/foreach_bucket +0 -88
- data/scripts/s3_cataloger/parse_ls.py +0 -391
- 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
- data/spec/server/config_spec.rb +0 -113
- data/spec/server/event_spec.rb +0 -103
- data/spec/server/itemset_legacy_spec.rb +0 -320
- data/spec/server/itemset_spec.rb +0 -317
- data/spec/server/rack/extract_methods_spec.rb +0 -60
- data/spec/server/rack/path_spec.rb +0 -36
- data/spec/server/rack/path_validation_spec.rb +0 -22
- data/spec/server/server_spec.rb +0 -20
- data/spec/support/mongo_cleaner.rb +0 -32
- data/src/main/java/ItemSetTest.java +0 -76
- data/src/main/java/com/infochimps/util/CurrentClass.java +0 -26
- data/src/main/java/com/infochimps/util/DebugUtil.java +0 -38
- data/src/main/java/com/infochimps/util/HttpHelper.java +0 -181
- data/src/main/java/com/infochimps/vayacondios/ItemSets.java +0 -373
- data/src/main/java/com/infochimps/vayacondios/LinkToVCD.java +0 -18
- data/src/main/java/com/infochimps/vayacondios/MemoryVCDShim.java +0 -84
- data/src/main/java/com/infochimps/vayacondios/Organization.java +0 -62
- data/src/main/java/com/infochimps/vayacondios/PathBuilder.java +0 -13
- data/src/main/java/com/infochimps/vayacondios/StandardVCDLink.java +0 -218
- data/src/main/java/com/infochimps/vayacondios/VCDIntegrationTest.java +0 -108
- data/src/test/java/com/infochimps/vayacondios/TestVayacondiosInMemory.java +0 -78
- data/vayacondios-client.gemspec +0 -25
@@ -0,0 +1,69 @@
|
|
1
|
+
module Vayacondios::Server
|
2
|
+
class StashHandler < DocumentHandler
|
3
|
+
|
4
|
+
# Create a stash.
|
5
|
+
#
|
6
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
7
|
+
# @param [Hash] document the body of the stash
|
8
|
+
def create(params, document)
|
9
|
+
stash = Stash.create(params, document) do |request|
|
10
|
+
database.call(:insert, request)
|
11
|
+
end
|
12
|
+
stash.delete(:topic)
|
13
|
+
stash
|
14
|
+
end
|
15
|
+
|
16
|
+
# Find and show a particular stash.
|
17
|
+
#
|
18
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
19
|
+
# @raise [Goliath::Validation::Error] if no stash is found. Returns a 404.
|
20
|
+
def retrieve(params, document)
|
21
|
+
stash = Stash.find(params) do |request|
|
22
|
+
database.call(:retrieve, request)
|
23
|
+
end or raise Goliath::Validation::NotFoundError.new("Stash with topic <#{params[:topic]}> not found")
|
24
|
+
stash.delete(:topic)
|
25
|
+
if slice = params[:id]
|
26
|
+
stash[slice.to_sym] or raise Goliath::Validation::NotFoundError.new("Stash with topic <#{params[:topic]}> found, but does not contain Id <#{slice}>")
|
27
|
+
else
|
28
|
+
stash
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Update a stash.
|
33
|
+
#
|
34
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
35
|
+
# @param [Hash] document the body of the stash
|
36
|
+
# def update(params, document)
|
37
|
+
# id = params.delete(:id)
|
38
|
+
# raise Goliath::Validation::BadRequestError.new("If not including an id the document must be a Hash") if id.blank? && !document.is_a?(Hash)
|
39
|
+
# # Not sure if I like this behavior for updating a non-existant document
|
40
|
+
# original = begin ; retrieve(params.dup, nil) ; rescue Goliath::Validation::NotFoundError ; nil ; end
|
41
|
+
# if original.is_a? Hash
|
42
|
+
# if id
|
43
|
+
# original.delete(id.to_sym)
|
44
|
+
# original.merge!(id => document) unless document.nil?
|
45
|
+
# else
|
46
|
+
# original.merge! document
|
47
|
+
# end
|
48
|
+
# else
|
49
|
+
# params[:id] = id if id && document
|
50
|
+
# original = document
|
51
|
+
# end
|
52
|
+
# Stash.update(params, original) do |request|
|
53
|
+
# database.call(:update, request)
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
|
57
|
+
# Delete a single stash.
|
58
|
+
#
|
59
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
60
|
+
# @param [Hash] document presentation or filter information
|
61
|
+
def delete(params, document)
|
62
|
+
raise Goliath::Validation::NotImplementedError.new 'Deleting an Id from a Stash is not supported' if params[:id]
|
63
|
+
Stash.destroy(params, {}) do |request, options|
|
64
|
+
database.call(:remove, request, options)
|
65
|
+
end
|
66
|
+
action_successful
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Vayacondios::Server
|
2
|
+
class StashesHandler < DocumentHandler
|
3
|
+
|
4
|
+
# Apply a replacement across many stashes.
|
5
|
+
#
|
6
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
7
|
+
# @param [Hash] document the body of the request containing a search query and a replacement
|
8
|
+
# def create(params, document)
|
9
|
+
# document.symbolize_keys!
|
10
|
+
# query = document[:query] || {}
|
11
|
+
# replacement = document[:update] || {}
|
12
|
+
# Stash.replace_many(params, query, replacement)
|
13
|
+
# end
|
14
|
+
|
15
|
+
# Search for stashes matching a given query.
|
16
|
+
#
|
17
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
18
|
+
# @param [Hash] query a search query
|
19
|
+
def retrieve(params, query)
|
20
|
+
stashes = Stash.search(params, query) do |request, filter, options|
|
21
|
+
database.call(:search, request, filter, options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Apply an update across many stashes.
|
26
|
+
#
|
27
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
28
|
+
# @param [Hash] document the body of the request containing a search query and an update
|
29
|
+
# def update(params={}, document={})
|
30
|
+
# query = (document[:query] || document['query'] || {})
|
31
|
+
# update = (document[:update] || document['update'] || {})
|
32
|
+
# Stash.update_many(log, database, params, query, update)
|
33
|
+
# end
|
34
|
+
|
35
|
+
# Delete many stashes that match a query.
|
36
|
+
#
|
37
|
+
# @param [Hash] params routing information like `organization`, `topic,`, or `id`
|
38
|
+
# @param [Hash] query a search query
|
39
|
+
# @param [Hash] document the body of the request containing a search query and an update
|
40
|
+
def delete(params, query)
|
41
|
+
raise Goliath::Validation::BadRequestError.new 'Query cannot be empty' if query.empty?
|
42
|
+
Stash.destroy(params, query) do |request, filter|
|
43
|
+
database.call(:remove, request, filter)
|
44
|
+
end
|
45
|
+
action_successful
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Vayacondios::Server
|
2
|
+
class StreamHandler < EventsHandler
|
3
|
+
|
4
|
+
attr_reader :cursor, :timer, :on_data
|
5
|
+
|
6
|
+
def retrieve(params, query)
|
7
|
+
@timer = EM::Synchrony.add_periodic_timer(1){ stream_events }
|
8
|
+
@cursor = Event.receive(params).prepare_search(query)
|
9
|
+
Goliath::Response::STREAMING
|
10
|
+
end
|
11
|
+
|
12
|
+
def stream_data(&on_data)
|
13
|
+
@on_data = on_data
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def close_stream!
|
18
|
+
timer.cancel
|
19
|
+
end
|
20
|
+
|
21
|
+
def update_cursor latest
|
22
|
+
cursor.filter.delete(:_t)
|
23
|
+
cursor.prepare_search(after: latest)
|
24
|
+
end
|
25
|
+
|
26
|
+
def stream_events
|
27
|
+
log.debug 'Streaming events'
|
28
|
+
log.debug " Stream cursor is #{cursor.filter}"
|
29
|
+
available = database.call(:search, cursor, cursor.filter.dup, {})
|
30
|
+
unless available.empty?
|
31
|
+
available.each do |result|
|
32
|
+
event = Event.new.format_response(result)
|
33
|
+
on_data.call event
|
34
|
+
update_cursor event[:time]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# The Document model is a base model used by Event, Stash, &c.
|
2
|
+
#
|
3
|
+
# The `organization` and `topic` properties are defined as instance
|
4
|
+
# attributes because they are used for routing the document.
|
5
|
+
# Subclasses should continue to store each separate piece of routing
|
6
|
+
# information as its own instance variable and store the entire
|
7
|
+
# payload/data as a single field.
|
8
|
+
#
|
9
|
+
# organization coca_cola
|
10
|
+
# |---- topic |---- ad_campaigns
|
11
|
+
# |---- ... ------> |---- web_traffic
|
12
|
+
# `---- topic `---- social_media_buzz
|
13
|
+
#
|
14
|
+
# @attr [String] organization the organization this document belongs to
|
15
|
+
# @attr [String] topic the unit which identifies documents of a given "kind"
|
16
|
+
module Vayacondios::Server
|
17
|
+
class Document
|
18
|
+
include Gorillib::Model
|
19
|
+
|
20
|
+
field :organization, String
|
21
|
+
field :topic, String
|
22
|
+
field :id, String
|
23
|
+
field :body, Hash
|
24
|
+
field :filter, Hash
|
25
|
+
|
26
|
+
def receive_organization name
|
27
|
+
@organization = sanitize_location_name(name).gsub(/^system\./, '_system.')
|
28
|
+
end
|
29
|
+
|
30
|
+
def format_response result
|
31
|
+
from_document(result.symbolize_keys.compact).external_document
|
32
|
+
end
|
33
|
+
|
34
|
+
# A class for errors that arise within documents due to internal or
|
35
|
+
# IO errors.
|
36
|
+
Error = Class.new(StandardError)
|
37
|
+
|
38
|
+
# Sanitize a string to make a suitable component of a database
|
39
|
+
# location name.
|
40
|
+
#
|
41
|
+
# Replaces all characters that aren't letters, digits, underscores,
|
42
|
+
# periods, or hyphens with underscores. Also replaces periods at
|
43
|
+
# the beginning or at the end of a collection name with an
|
44
|
+
# underscore.
|
45
|
+
#
|
46
|
+
# @param [String] name
|
47
|
+
# @return [String] the sanitized `name`
|
48
|
+
def sanitize_location_name name
|
49
|
+
name.to_s.gsub(/^\.|[^-\w\.]+|\.$/, '_')
|
50
|
+
end
|
51
|
+
|
52
|
+
class << self
|
53
|
+
def extract_query_options! params
|
54
|
+
params.symbolize_keys!
|
55
|
+
opts = {}
|
56
|
+
[:limit, :order, :sort, :fields].each{ |opt| opts[opt] = params.delete opt }
|
57
|
+
opts.merge default_query_options
|
58
|
+
end
|
59
|
+
|
60
|
+
def search(params, query, &driver)
|
61
|
+
options = extract_query_options! query
|
62
|
+
action = receive(params).prepare_search(query)
|
63
|
+
result = driver.call(action, action.filter, options)
|
64
|
+
result.map{ |res| new.format_response res }
|
65
|
+
end
|
66
|
+
|
67
|
+
def create(params, document, &driver)
|
68
|
+
action = receive(params).prepare_create(document)
|
69
|
+
result = driver.call(action)
|
70
|
+
action.format_response result
|
71
|
+
end
|
72
|
+
|
73
|
+
def find(params, &driver)
|
74
|
+
action = receive(params).prepare_find
|
75
|
+
result = driver.call(action, {})
|
76
|
+
return nil if result.nil?
|
77
|
+
action.format_response result
|
78
|
+
end
|
79
|
+
|
80
|
+
def destroy(params, document, &driver)
|
81
|
+
action = receive(params).prepare_destroy(document.symbolize_keys)
|
82
|
+
result = driver.call(action, action.filter)
|
83
|
+
return result
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
# Events are documents with arbitrary key/value data but which also
|
2
|
+
# have
|
3
|
+
#
|
4
|
+
# * an ID, auto-generated to a random unique value when none is provided
|
5
|
+
# * a timestamp, auto-generated to the current time when none is provided
|
6
|
+
#
|
7
|
+
# An HTTP request which announces a new event
|
8
|
+
#
|
9
|
+
# ```
|
10
|
+
# POST /v2/coca_cola/event/ad_campaigns
|
11
|
+
# { "impresions": 23829, "errors": 29 }
|
12
|
+
# ```
|
13
|
+
#
|
14
|
+
# would result in a document in the `coca_cola.ad_campaigns.events`
|
15
|
+
# collection with the following structure:
|
16
|
+
#
|
17
|
+
# ```
|
18
|
+
# {
|
19
|
+
# "_id": ObjectId("51c38ad981bdb34d32000001"),
|
20
|
+
# "t": ISODate("2013-06-20T23:06:01.846Z"),
|
21
|
+
# "d": {
|
22
|
+
# "impressions": 23829,
|
23
|
+
# "errors": 29
|
24
|
+
# }
|
25
|
+
# }
|
26
|
+
# ```
|
27
|
+
#
|
28
|
+
# When explictly setting the ID and timestamp with a request like:
|
29
|
+
#
|
30
|
+
# ```
|
31
|
+
# POST /v2/coca_cola/event/ad_campaigns/atx-jan-01
|
32
|
+
# { "impresions": 23829, "errors": 29, "time": "2013-01-20 18:09:39 -0500" }
|
33
|
+
# ```
|
34
|
+
#
|
35
|
+
# a document would still be generated in the
|
36
|
+
# `coca_cola.ad_campaigns.events` collection with a similar structure:
|
37
|
+
#
|
38
|
+
# ```
|
39
|
+
# {
|
40
|
+
# "_id": "atx-jan-01",
|
41
|
+
# "t": ISODate("2013-01-20T23:09:39Z")
|
42
|
+
# "d": {
|
43
|
+
# "impressions": 23829,
|
44
|
+
# "errors": 29
|
45
|
+
# }
|
46
|
+
# }
|
47
|
+
# ```
|
48
|
+
#
|
49
|
+
# @attr [Time] timestamp the timestamp for which this event records data
|
50
|
+
#
|
51
|
+
module Vayacondios::Server
|
52
|
+
class Event < Vayacondios::Server::Document
|
53
|
+
|
54
|
+
# The default number of events returned when searching.
|
55
|
+
LIMIT = 50
|
56
|
+
|
57
|
+
# The default sort order when searching
|
58
|
+
ORDER = 'descending'
|
59
|
+
|
60
|
+
# The default sort field when searching.
|
61
|
+
SORT = 'time'
|
62
|
+
|
63
|
+
# The default time window (measured relative to the current time)
|
64
|
+
# when searching.
|
65
|
+
WINDOW = 3600
|
66
|
+
|
67
|
+
def self.default_query_options
|
68
|
+
{ limit: LIMIT, order: ORDER, sort: SORT }
|
69
|
+
end
|
70
|
+
|
71
|
+
field :time, Time # assigned or Time.now.utc
|
72
|
+
field :host, String # assigned or read from the client
|
73
|
+
|
74
|
+
# Set the topic of this document, sanitizing it for the database
|
75
|
+
#
|
76
|
+
# @param [String] name
|
77
|
+
# @return [String] the sanitized `name`
|
78
|
+
def receive_topic name
|
79
|
+
@topic = sanitize_location_name name
|
80
|
+
end
|
81
|
+
|
82
|
+
# Normalizes the time
|
83
|
+
def receive_time t
|
84
|
+
@time = format_time to_timestamp(t)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Parses an object into a timestamp.
|
88
|
+
#
|
89
|
+
# @param [String, Numeric, Time, nil] obj
|
90
|
+
# @param [Time] default the time value to return if none could be found in the `obj`
|
91
|
+
# @return [Time]
|
92
|
+
def to_timestamp(obj, default = Time.now)
|
93
|
+
case obj
|
94
|
+
when String then Time.parse(obj)
|
95
|
+
when Date then obj.to_time
|
96
|
+
when Time then obj
|
97
|
+
when Numeric then Time.at(obj)
|
98
|
+
else default
|
99
|
+
end
|
100
|
+
rescue ArgumentError => e
|
101
|
+
default
|
102
|
+
end
|
103
|
+
|
104
|
+
def format_time ts
|
105
|
+
ts.round(3).utc
|
106
|
+
end
|
107
|
+
|
108
|
+
# The name of the collection this event will store its data in.
|
109
|
+
#
|
110
|
+
# @return [String]
|
111
|
+
def location
|
112
|
+
[organization, topic, 'events'].join('.')
|
113
|
+
end
|
114
|
+
|
115
|
+
# An events internal database representation
|
116
|
+
def document
|
117
|
+
{ _id: id, _t: time, _d: body }.compact
|
118
|
+
end
|
119
|
+
|
120
|
+
# Populate a new Event from a database representation
|
121
|
+
def from_document doc
|
122
|
+
d = {}.tap do |d|
|
123
|
+
d[:id] = doc[:_id]
|
124
|
+
d[:time] = doc[:_t]
|
125
|
+
d[:body] = doc[:_d]
|
126
|
+
end.compact
|
127
|
+
receive! d
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
# An event as presented to a user
|
132
|
+
def external_document
|
133
|
+
{ id: id, time: time.iso8601(3) }.merge(body)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns a Hash that can be used for selection criteria in a query
|
137
|
+
# to a MongoDB collection.
|
138
|
+
#
|
139
|
+
# For any given `query` object, this method should be run **after**
|
140
|
+
# Event.projector because Event.projector modifies the `query` by
|
141
|
+
# removing certain special options which would otherwise be
|
142
|
+
# interpreted by this method..
|
143
|
+
#
|
144
|
+
# @param [Hash] query
|
145
|
+
# @option query [String, Numeric, Time, nil] from the earliest time for a matched event (>=)
|
146
|
+
# @option query [String, Numeric, Time, nil] upto the latest time for a matched event (<=)
|
147
|
+
# @option query [String, Numeric, Time, nil] after the earliest time for a matched event (>)
|
148
|
+
# @option query [String, Numeric, Time, nil] before the latest time for a matched event (<)
|
149
|
+
# @option query [String, Regexp]] id a regular expression that matches the ID of the event
|
150
|
+
# @return [Hash] the selector Hash
|
151
|
+
# @see Event.projector
|
152
|
+
def event_filter query
|
153
|
+
filter = { _t: {} }.tap do |filter|
|
154
|
+
if query.has_key? :after
|
155
|
+
filter[:_t][:gt] = to_timestamp query.delete(:after)
|
156
|
+
query.delete(:from)
|
157
|
+
elsif query.has_key? :from
|
158
|
+
filter[:_t][:gte] = to_timestamp query.delete(:from)
|
159
|
+
end
|
160
|
+
|
161
|
+
if query.has_key? :before
|
162
|
+
filter[:_t][:lt] = to_timestamp query.delete(:before)
|
163
|
+
query.delete(:upto)
|
164
|
+
elsif query.has_key? :upto
|
165
|
+
filter[:_t][:lte] = to_timestamp query.delete(:upto)
|
166
|
+
end
|
167
|
+
# sel['_id'] = Regexp.new(query.delete(:id)) if query[:id]
|
168
|
+
query.each_pair{ |key, val| filter[:_d] ||= {} ; filter[:_d][key] = val }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Prepare Event search request
|
173
|
+
def prepare_search query
|
174
|
+
receive!(filter: event_filter(query))
|
175
|
+
self
|
176
|
+
end
|
177
|
+
|
178
|
+
# Prepare Event retrieve request
|
179
|
+
def prepare_find
|
180
|
+
raise Error.new('Cannot find an event without an ID') if id.blank?
|
181
|
+
self
|
182
|
+
end
|
183
|
+
|
184
|
+
# Prepare Event create request
|
185
|
+
def prepare_create document
|
186
|
+
raise Error.new('Events must be Hash-like to create') unless document.is_a?(Hash)
|
187
|
+
document.symbolize_keys!
|
188
|
+
receive!(time: document.delete(:time), body: document)
|
189
|
+
self
|
190
|
+
end
|
191
|
+
|
192
|
+
# Prepare Event remove request
|
193
|
+
def prepare_destroy query
|
194
|
+
receive!(filter: event_filter(query))
|
195
|
+
self
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Stashes are documents with arbitrary key/value data.
|
2
|
+
#
|
3
|
+
# An HTTP request which sets a new stash
|
4
|
+
#
|
5
|
+
# ```
|
6
|
+
# POST /v2/coca_cola/stash/campaigns
|
7
|
+
# { "creatives": [ "atx-jan-01", "bos-jan-01"], "test": false }
|
8
|
+
# ```
|
9
|
+
#
|
10
|
+
# would result in a document in the `coca_cola.stash` collection with
|
11
|
+
# the following structure:
|
12
|
+
#
|
13
|
+
# ```
|
14
|
+
# {
|
15
|
+
# "_id": "campaigns",
|
16
|
+
# "creatives": [ "atx-jan-01", "bos-jan-01"],
|
17
|
+
# "test": false
|
18
|
+
# }
|
19
|
+
# ```
|
20
|
+
#
|
21
|
+
module Vayacondios::Server
|
22
|
+
class Stash < Vayacondios::Server::Document
|
23
|
+
|
24
|
+
# The default number of stashes returned when searching.
|
25
|
+
LIMIT = 50
|
26
|
+
|
27
|
+
# The default sort order when searching.
|
28
|
+
SORT = 'ascending'
|
29
|
+
ORDER = '_id'
|
30
|
+
|
31
|
+
# Returned as an acknowledgement of the request when there is no
|
32
|
+
# better option (#destroy, #update_many, &c.)
|
33
|
+
# OK = {ok: true}
|
34
|
+
|
35
|
+
def self.default_query_options
|
36
|
+
{ limit: LIMIT, order: ORDER, sort: SORT }
|
37
|
+
end
|
38
|
+
|
39
|
+
# The name of the collection this stash will store its data in.
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def location
|
43
|
+
[organization.to_s, 'stash'].join('.')
|
44
|
+
end
|
45
|
+
|
46
|
+
def document
|
47
|
+
{ _id: topic }.compact.merge(body || {})
|
48
|
+
end
|
49
|
+
|
50
|
+
def from_document doc
|
51
|
+
d = {}.tap do |d|
|
52
|
+
d[:topic] = doc.delete(:_id)
|
53
|
+
doc = nil if doc.empty?
|
54
|
+
if body.nil?
|
55
|
+
new_body = doc
|
56
|
+
else
|
57
|
+
new_body = body.merge(doc || {})
|
58
|
+
end
|
59
|
+
d[:body] = new_body
|
60
|
+
end
|
61
|
+
receive! d
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
def external_document
|
66
|
+
{ topic: topic }.merge(body || {})
|
67
|
+
end
|
68
|
+
|
69
|
+
def prepare_search query
|
70
|
+
filter = query.merge(_id: topic).compact
|
71
|
+
receive!(filter: filter)
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def prepare_create document
|
76
|
+
if document.is_a? Hash
|
77
|
+
document.symbolize_keys!
|
78
|
+
raise Error.new ':topic is a reserved key and cannot be used in a stash document' if document.has_key?(:topic)
|
79
|
+
end
|
80
|
+
if id.blank?
|
81
|
+
raise Error.new 'If not including an Id, the document must be a Hash' unless document.is_a? Hash
|
82
|
+
receive!(body: document)
|
83
|
+
else
|
84
|
+
receive!(body: { id => document })
|
85
|
+
end
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
def prepare_find
|
90
|
+
raise Error.new('Cannot find a stash without a topic') unless topic
|
91
|
+
self
|
92
|
+
end
|
93
|
+
|
94
|
+
def prepare_destroy query
|
95
|
+
filter = query.merge(_id: topic).compact
|
96
|
+
receive!(filter: filter)
|
97
|
+
self
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'goliath'
|
2
|
+
require 'goliath/chimp'
|
3
|
+
require 'em-mongo'
|
4
|
+
require 'em-synchrony/em-http'
|
5
|
+
require 'em-synchrony/em-mongo'
|
6
|
+
require 'configliere'
|
7
|
+
|
8
|
+
require 'gorillib/object/blank'
|
9
|
+
require 'gorillib/enumerable/sum'
|
10
|
+
require 'gorillib/hash/compact'
|
11
|
+
require 'gorillib/hash/deep_merge'
|
12
|
+
require 'gorillib/hash/keys'
|
13
|
+
require 'gorillib/model'
|
14
|
+
require 'gorillib/string/constantize'
|
15
|
+
require 'gorillib/string/inflections'
|
16
|
+
require 'multi_json'
|
17
|
+
|
18
|
+
require 'vayacondios'
|
19
|
+
require 'vayacondios/configuration'
|
20
|
+
|
21
|
+
require 'vayacondios/server/api_options'
|
22
|
+
require 'vayacondios/server/configuration'
|
23
|
+
require 'vayacondios/server/driver'
|
24
|
+
require 'vayacondios/server/drivers/mongo'
|
25
|
+
|
26
|
+
require 'vayacondios/server/models/document'
|
27
|
+
require 'vayacondios/server/models/event'
|
28
|
+
require 'vayacondios/server/models/stash'
|
29
|
+
|
30
|
+
require 'vayacondios/server/handlers/document_handler'
|
31
|
+
require 'vayacondios/server/handlers/event_handler'
|
32
|
+
require 'vayacondios/server/handlers/events_handler'
|
33
|
+
require 'vayacondios/server/handlers/stash_handler'
|
34
|
+
require 'vayacondios/server/handlers/stashes_handler'
|
35
|
+
require 'vayacondios/server/handlers/stream_handler'
|
data/lib/vayacondios-server.rb
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
require 'goliath'
|
2
|
+
require 'goliath/chimp'
|
2
3
|
require 'em-mongo'
|
3
4
|
require 'em-synchrony/em-http'
|
4
5
|
require 'em-synchrony/em-mongo'
|
6
|
+
require 'configliere'
|
5
7
|
|
6
8
|
require 'gorillib/object/blank'
|
7
9
|
require 'gorillib/enumerable/sum'
|
10
|
+
require 'gorillib/hash/compact'
|
8
11
|
require 'gorillib/hash/deep_merge'
|
9
12
|
require 'gorillib/hash/keys'
|
13
|
+
require 'gorillib/model'
|
10
14
|
require 'gorillib/string/constantize'
|
11
15
|
require 'gorillib/string/inflections'
|
12
16
|
require 'multi_json'
|
13
17
|
|
14
|
-
require 'vayacondios
|
15
|
-
require 'vayacondios/
|
18
|
+
require 'vayacondios'
|
19
|
+
require 'vayacondios/configuration'
|
16
20
|
|
17
|
-
require 'vayacondios/server/
|
18
|
-
require 'vayacondios/server/
|
19
|
-
require 'vayacondios/server/
|
21
|
+
require 'vayacondios/server/api_options'
|
22
|
+
require 'vayacondios/server/configuration'
|
23
|
+
require 'vayacondios/server/driver'
|
24
|
+
require 'vayacondios/server/drivers/mongo'
|
20
25
|
|
21
|
-
require 'vayacondios/server/
|
22
|
-
require 'vayacondios/server/
|
23
|
-
require 'vayacondios/server/
|
26
|
+
require 'vayacondios/server/models/document'
|
27
|
+
require 'vayacondios/server/models/event'
|
28
|
+
require 'vayacondios/server/models/stash'
|
24
29
|
|
25
|
-
require 'vayacondios/server/
|
26
|
-
require 'vayacondios/server/
|
27
|
-
require 'vayacondios/server/
|
28
|
-
require 'vayacondios/server/
|
29
|
-
require 'vayacondios/server/
|
30
|
+
require 'vayacondios/server/handlers/document_handler'
|
31
|
+
require 'vayacondios/server/handlers/event_handler'
|
32
|
+
require 'vayacondios/server/handlers/events_handler'
|
33
|
+
require 'vayacondios/server/handlers/stash_handler'
|
34
|
+
require 'vayacondios/server/handlers/stashes_handler'
|
35
|
+
require 'vayacondios/server/handlers/stream_handler'
|
data/lib/vayacondios.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Vayacondios
|
2
|
+
# Version of the api
|
3
|
+
API_VERSION = 'v3'
|
4
|
+
|
5
|
+
# Gem version for both client and server
|
6
|
+
GEM_VERSION = '0.3.0'
|
7
|
+
|
8
|
+
# Default port to find/connect to for the server
|
9
|
+
DEFAULT_SERVER_PORT = 3467
|
10
|
+
|
11
|
+
# Default address to bind/connect to for the server
|
12
|
+
DEFAULT_SERVER_ADDRESS = 'localhost'
|
13
|
+
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def library_dir
|
17
|
+
File.expand_path('../..', __FILE__)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Alias for Vayacondios
|
22
|
+
Vcd = Vayacondios
|