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.
Files changed (142) hide show
  1. data/.gitignore +3 -1
  2. data/.travis.yml +2 -0
  3. data/Gemfile +15 -9
  4. data/LICENSE.md +2 -6
  5. data/Procfile +1 -1
  6. data/README.md +656 -111
  7. data/Rakefile +89 -6
  8. data/bin/vcd +10 -0
  9. data/bin/vcd-server +8 -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/config/vcd-server.rb +37 -0
  14. data/examples/configuration.rb +56 -0
  15. data/examples/event_stream.rb +19 -0
  16. data/examples/simple.rb +61 -0
  17. data/features/event.feature +319 -0
  18. data/features/events.feature +208 -0
  19. data/features/stash.feature +840 -0
  20. data/features/stashes.feature +492 -0
  21. data/features/step_definitions/stash_steps.rb +113 -0
  22. data/features/stream.feature +30 -0
  23. data/features/support/em.rb +14 -0
  24. data/features/support/env.rb +13 -0
  25. data/lib/vayacondios/configuration.rb +63 -0
  26. data/lib/vayacondios/server/api.rb +126 -0
  27. data/lib/vayacondios/server/api_options.rb +56 -0
  28. data/lib/vayacondios/server/configuration.rb +23 -0
  29. data/lib/vayacondios/server/driver.rb +71 -0
  30. data/lib/vayacondios/server/drivers/mongo.rb +126 -0
  31. data/lib/vayacondios/server/handlers/document_handler.rb +81 -0
  32. data/lib/vayacondios/server/handlers/event_handler.rb +31 -26
  33. data/lib/vayacondios/server/handlers/events_handler.rb +31 -0
  34. data/lib/vayacondios/server/handlers/stash_handler.rb +69 -0
  35. data/lib/vayacondios/server/handlers/stashes_handler.rb +49 -0
  36. data/lib/vayacondios/server/handlers/stream_handler.rb +39 -0
  37. data/lib/vayacondios/server/models/document.rb +87 -0
  38. data/lib/vayacondios/server/models/event.rb +198 -0
  39. data/lib/vayacondios/server/models/stash.rb +100 -0
  40. data/lib/vayacondios/server.rb +35 -0
  41. data/lib/vayacondios-server.rb +19 -13
  42. data/lib/vayacondios.rb +22 -0
  43. data/pom.xml +124 -4
  44. data/spec/configuration_spec.rb +41 -0
  45. data/spec/server/api_options_spec.rb +32 -0
  46. data/spec/server/api_spec.rb +279 -0
  47. data/spec/server/configuration_spec.rb +27 -0
  48. data/spec/server/drivers/mongo_spec.rb +107 -0
  49. data/spec/server/handlers/event_handler_spec.rb +62 -0
  50. data/spec/server/handlers/events_handler_spec.rb +51 -0
  51. data/spec/server/handlers/stash_handler_spec.rb +68 -0
  52. data/spec/server/handlers/stashes_handler_spec.rb +50 -0
  53. data/spec/server/handlers/stream_handler_spec.rb +5 -0
  54. data/spec/server/models/document_spec.rb +9 -0
  55. data/spec/server/models/event_spec.rb +185 -0
  56. data/spec/server/models/stash_spec.rb +95 -0
  57. data/spec/spec_helper.rb +23 -3
  58. data/spec/support/database_helper.rb +42 -0
  59. data/spec/support/log_helper.rb +19 -0
  60. data/spec/support/shared_context_for_events.rb +22 -0
  61. data/spec/support/shared_context_for_stashes.rb +24 -0
  62. data/spec/support/shared_examples_for_handlers.rb +32 -0
  63. data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
  64. data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
  65. data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +487 -65
  66. data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
  67. data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
  68. data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
  69. data/vayacondios-server.gemspec +9 -9
  70. metadata +127 -122
  71. checksums.yaml +0 -15
  72. data/.rspec +0 -2
  73. data/.yardopts +0 -10
  74. data/Guardfile +0 -41
  75. data/app/http_shim.rb +0 -71
  76. data/bin/vcd.sh +0 -27
  77. data/config/http_shim.rb +0 -43
  78. data/config/vayacondios.example.yaml +0 -7
  79. data/config/vayacondios.yaml +0 -7
  80. data/examples/java/ItemSetTest.java +0 -76
  81. data/lib/tasks/publish.rake +0 -23
  82. data/lib/tasks/spec.rake +0 -11
  83. data/lib/tasks/yard.rake +0 -2
  84. data/lib/vayacondios/client/config.rb +0 -7
  85. data/lib/vayacondios/client/configliere.rb +0 -38
  86. data/lib/vayacondios/client/cube_client.rb +0 -39
  87. data/lib/vayacondios/client/http_client.rb +0 -49
  88. data/lib/vayacondios/client/itemset.rb +0 -130
  89. data/lib/vayacondios/client/legacy_switch.rb +0 -43
  90. data/lib/vayacondios/client/notifier.rb +0 -123
  91. data/lib/vayacondios/client/zabbix_client.rb +0 -148
  92. data/lib/vayacondios/legacy_switch.rb +0 -43
  93. data/lib/vayacondios/server/errors/bad_request.rb +0 -6
  94. data/lib/vayacondios/server/errors/not_found.rb +0 -6
  95. data/lib/vayacondios/server/handlers/config_handler.rb +0 -32
  96. data/lib/vayacondios/server/handlers/itemset_handler.rb +0 -60
  97. data/lib/vayacondios/server/legacy_switch.rb +0 -43
  98. data/lib/vayacondios/server/model/config_document.rb +0 -89
  99. data/lib/vayacondios/server/model/document.rb +0 -25
  100. data/lib/vayacondios/server/model/event_document.rb +0 -94
  101. data/lib/vayacondios/server/model/itemset_document.rb +0 -126
  102. data/lib/vayacondios/server/rack/extract_methods.rb +0 -35
  103. data/lib/vayacondios/server/rack/jsonize.rb +0 -43
  104. data/lib/vayacondios/server/rack/params.rb +0 -50
  105. data/lib/vayacondios/server/rack/path.rb +0 -23
  106. data/lib/vayacondios/server/rack/path_validation.rb +0 -22
  107. data/lib/vayacondios/version.rb +0 -3
  108. data/lib/vayacondios-client.rb +0 -22
  109. data/scripts/hadoop_monitor/configurable.rb +0 -66
  110. data/scripts/hadoop_monitor/hadoop_attempt_scraper.rb +0 -45
  111. data/scripts/hadoop_monitor/hadoop_client.rb +0 -273
  112. data/scripts/hadoop_monitor/hadoop_monitor.rb +0 -101
  113. data/scripts/hadoop_monitor/hadoopable.rb +0 -65
  114. data/scripts/hadoop_monitor/machine_monitor.rb +0 -115
  115. data/scripts/s3_cataloger/buckets +0 -33
  116. data/scripts/s3_cataloger/foreach_bucket +0 -88
  117. data/scripts/s3_cataloger/parse_ls.py +0 -391
  118. data/spec/client/itemset_legacy_spec.rb +0 -55
  119. data/spec/client/itemset_spec.rb +0 -60
  120. data/spec/client/notifier_spec.rb +0 -120
  121. data/spec/server/config_spec.rb +0 -113
  122. data/spec/server/event_spec.rb +0 -103
  123. data/spec/server/itemset_legacy_spec.rb +0 -320
  124. data/spec/server/itemset_spec.rb +0 -317
  125. data/spec/server/rack/extract_methods_spec.rb +0 -60
  126. data/spec/server/rack/path_spec.rb +0 -36
  127. data/spec/server/rack/path_validation_spec.rb +0 -22
  128. data/spec/server/server_spec.rb +0 -20
  129. data/spec/support/mongo_cleaner.rb +0 -32
  130. data/src/main/java/ItemSetTest.java +0 -76
  131. data/src/main/java/com/infochimps/util/CurrentClass.java +0 -26
  132. data/src/main/java/com/infochimps/util/DebugUtil.java +0 -38
  133. data/src/main/java/com/infochimps/util/HttpHelper.java +0 -181
  134. data/src/main/java/com/infochimps/vayacondios/ItemSets.java +0 -373
  135. data/src/main/java/com/infochimps/vayacondios/LinkToVCD.java +0 -18
  136. data/src/main/java/com/infochimps/vayacondios/MemoryVCDShim.java +0 -84
  137. data/src/main/java/com/infochimps/vayacondios/Organization.java +0 -62
  138. data/src/main/java/com/infochimps/vayacondios/PathBuilder.java +0 -13
  139. data/src/main/java/com/infochimps/vayacondios/StandardVCDLink.java +0 -218
  140. data/src/main/java/com/infochimps/vayacondios/VCDIntegrationTest.java +0 -108
  141. data/src/test/java/com/infochimps/vayacondios/TestVayacondiosInMemory.java +0 -78
  142. 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'
@@ -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/server/errors/bad_request'
15
- require 'vayacondios/server/errors/not_found'
18
+ require 'vayacondios'
19
+ require 'vayacondios/configuration'
16
20
 
17
- require 'vayacondios/server/model/config_document'
18
- require 'vayacondios/server/model/event_document'
19
- require 'vayacondios/server/model/itemset_document'
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/handlers/config_handler'
22
- require 'vayacondios/server/handlers/event_handler'
23
- require 'vayacondios/server/handlers/itemset_handler'
26
+ require 'vayacondios/server/models/document'
27
+ require 'vayacondios/server/models/event'
28
+ require 'vayacondios/server/models/stash'
24
29
 
25
- require 'vayacondios/server/rack/extract_methods'
26
- require 'vayacondios/server/rack/params'
27
- require 'vayacondios/server/rack/jsonize'
28
- require 'vayacondios/server/rack/path'
29
- require 'vayacondios/server/rack/path_validation'
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'
@@ -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