vayacondios-server 0.3.1 → 0.3.2
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/Gemfile +2 -0
- data/config/vcd-server.rb +4 -4
- data/features/events.feature +142 -2
- data/features/stashes.feature +106 -5
- data/lib/vayacondios.rb +1 -1
- data/lib/vayacondios/server/api_options.rb +5 -3
- data/lib/vayacondios/server/configuration.rb +8 -6
- data/lib/vayacondios/server/drivers/mongo.rb +13 -10
- data/lib/vayacondios/server/models/document.rb +12 -4
- data/lib/vayacondios/server/models/event.rb +22 -8
- data/lib/vayacondios/server/models/stash.rb +7 -7
- data/spec/server/api_options_spec.rb +1 -1
- data/spec/server/configuration_spec.rb +31 -10
- data/spec/server/models/document_spec.rb +50 -3
- data/vayacondios-server.gemspec +1 -1
- metadata +6 -6
data/Gemfile
CHANGED
@@ -2,6 +2,8 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# em-mongo is too loose with its dependencies; 2.0.0 bson breaks vcd
|
4
4
|
gem 'bson', '1.9.2'
|
5
|
+
# cookiejar 0.3.1 has busted file permissions WTF
|
6
|
+
gem 'cookiejar', '0.3.0'
|
5
7
|
|
6
8
|
gemspec name: 'vayacondios-server'
|
7
9
|
gemspec name: 'vayacondios-client'
|
data/config/vcd-server.rb
CHANGED
@@ -10,10 +10,10 @@
|
|
10
10
|
# The production environment uses EventMachine::Synchrony to define a
|
11
11
|
# shared pool of open connections to the database. The size of this pool
|
12
12
|
# can be on the command-line with the --database.connections option.
|
13
|
-
Vayacondios::Server::DbConfig.overlay options
|
13
|
+
Vayacondios::Server::DbConfig.overlay options
|
14
14
|
|
15
15
|
environment(:production) do
|
16
|
-
db_options = Vayacondios::Server::DbConfig.env
|
16
|
+
db_options = Vayacondios::Server::DbConfig.env(:production)[:database]
|
17
17
|
driver = Vayacondios::Server::Driver.retrieve db_options[:driver]
|
18
18
|
logger.info("Opening #{db_options[:connections]} connections to #{db_options[:host]}:#{db_options[:port]} using #{driver}.")
|
19
19
|
config['db'] = EventMachine::Synchrony::ConnectionPool.new(size: db_options[:connections]) do
|
@@ -23,14 +23,14 @@ end
|
|
23
23
|
|
24
24
|
# The development environment uses a single database connection.
|
25
25
|
environment(:development) do
|
26
|
-
db_options = Vayacondios::Server::DbConfig.env
|
26
|
+
db_options = Vayacondios::Server::DbConfig.env(:development)[:database]
|
27
27
|
driver = Vayacondios::Server::Driver.retrieve db_options[:driver]
|
28
28
|
logger.info("Connecting to #{db_options[:host]}:#{db_options[:port]} using #{driver}.")
|
29
29
|
config['db'] = driver.connect db_options.merge(log: logger)
|
30
30
|
end
|
31
31
|
|
32
32
|
environment(:test) do
|
33
|
-
db_options = Vayacondios::Server::DbConfig.env
|
33
|
+
db_options = Vayacondios::Server::DbConfig.env(:test)[:database]
|
34
34
|
driver = Vayacondios::Server::Driver.retrieve db_options[:driver]
|
35
35
|
logger.info("Connecting to #{db_options[:host]}:#{db_options[:port]} using #{driver}.")
|
36
36
|
config['db'] = driver.connect db_options.merge(log: logger)
|
data/features/events.feature
CHANGED
@@ -86,6 +86,146 @@ Feature: Events
|
|
86
86
|
]
|
87
87
|
"""
|
88
88
|
|
89
|
+
Scenario: Retrieving Existing Events with a Limit Query
|
90
|
+
Given the following Event exists under topic "topic" in the database:
|
91
|
+
"""
|
92
|
+
{
|
93
|
+
"_id": "id1",
|
94
|
+
"_t": "2012-02-13T12:34:42.452Z",
|
95
|
+
"_d": {
|
96
|
+
"alignment": "good"
|
97
|
+
}
|
98
|
+
}
|
99
|
+
"""
|
100
|
+
And the following Event exists under topic "topic" in the database:
|
101
|
+
"""
|
102
|
+
{
|
103
|
+
"_id": "id2",
|
104
|
+
"_t": "2012-02-13T12:34:42.452Z",
|
105
|
+
"_d": {
|
106
|
+
"alignment": "evil"
|
107
|
+
}
|
108
|
+
}
|
109
|
+
"""
|
110
|
+
When the client sends a GET request to "/v3/organization/events/topic" with the following body:
|
111
|
+
"""
|
112
|
+
{
|
113
|
+
"sort": "alignment",
|
114
|
+
"order": "desc",
|
115
|
+
"limit": 1
|
116
|
+
}
|
117
|
+
"""
|
118
|
+
Then the response status should be 200
|
119
|
+
And the response body should be:
|
120
|
+
"""
|
121
|
+
[
|
122
|
+
{
|
123
|
+
"id": "id1",
|
124
|
+
"time": "2012-02-13T12:34:42.452Z",
|
125
|
+
"alignment": "good"
|
126
|
+
}
|
127
|
+
]
|
128
|
+
"""
|
129
|
+
|
130
|
+
Scenario: Retrieving Existing Events with a Sort Query
|
131
|
+
Given the following Event exists under topic "topic" in the database:
|
132
|
+
"""
|
133
|
+
{
|
134
|
+
"_id": "id1",
|
135
|
+
"_t": "2012-02-13T12:34:43.452Z",
|
136
|
+
"_d": {
|
137
|
+
"alignment": "good"
|
138
|
+
}
|
139
|
+
}
|
140
|
+
"""
|
141
|
+
And the following Event exists under topic "topic" in the database:
|
142
|
+
"""
|
143
|
+
{
|
144
|
+
"_id": "id2",
|
145
|
+
"_t": "2012-02-13T12:34:42.452Z",
|
146
|
+
"_d": {
|
147
|
+
"alignment": "neutral"
|
148
|
+
}
|
149
|
+
}
|
150
|
+
"""
|
151
|
+
And the following Event exists under topic "topic" in the database:
|
152
|
+
"""
|
153
|
+
{
|
154
|
+
"_id": "id3",
|
155
|
+
"_t": "2012-02-13T12:34:45.452Z",
|
156
|
+
"_d": {
|
157
|
+
"alignment": "evil"
|
158
|
+
}
|
159
|
+
}
|
160
|
+
"""
|
161
|
+
When the client sends a GET request to "/v3/organization/events/topic" with the following body:
|
162
|
+
"""
|
163
|
+
{
|
164
|
+
"sort": "alignment",
|
165
|
+
"order": "asc"
|
166
|
+
}
|
167
|
+
"""
|
168
|
+
Then the response status should be 200
|
169
|
+
And the response body should be:
|
170
|
+
"""
|
171
|
+
[
|
172
|
+
{
|
173
|
+
"id": "id3",
|
174
|
+
"time": "2012-02-13T12:34:45.452Z",
|
175
|
+
"alignment": "evil"
|
176
|
+
},
|
177
|
+
{
|
178
|
+
"id": "id1",
|
179
|
+
"time": "2012-02-13T12:34:43.452Z",
|
180
|
+
"alignment": "good"
|
181
|
+
},
|
182
|
+
{
|
183
|
+
"id": "id2",
|
184
|
+
"time": "2012-02-13T12:34:42.452Z",
|
185
|
+
"alignment": "neutral"
|
186
|
+
}
|
187
|
+
]
|
188
|
+
"""
|
189
|
+
|
190
|
+
Scenario: Retrieving Existing Events with a Fields Query
|
191
|
+
Given the following Event exists under topic "topic" in the database:
|
192
|
+
"""
|
193
|
+
{
|
194
|
+
"_id": "id1",
|
195
|
+
"_t": "2012-02-13T12:34:42.452Z",
|
196
|
+
"_d": {
|
197
|
+
"alignment": "good"
|
198
|
+
}
|
199
|
+
}
|
200
|
+
"""
|
201
|
+
And the following Event exists under topic "topic" in the database:
|
202
|
+
"""
|
203
|
+
{
|
204
|
+
"_id": "id2",
|
205
|
+
"_t": "2012-02-13T12:34:42.452Z",
|
206
|
+
"_d": {
|
207
|
+
"alignment": "evil"
|
208
|
+
}
|
209
|
+
}
|
210
|
+
"""
|
211
|
+
When the client sends a GET request to "/v3/organization/events/topic" with the following body:
|
212
|
+
"""
|
213
|
+
{
|
214
|
+
"alignment": "good",
|
215
|
+
"fields": ["alignment", "id"]
|
216
|
+
}
|
217
|
+
"""
|
218
|
+
Then the response status should be 200
|
219
|
+
And the response body should be:
|
220
|
+
"""
|
221
|
+
[
|
222
|
+
{
|
223
|
+
"id": "id1",
|
224
|
+
"alignment": "good"
|
225
|
+
}
|
226
|
+
]
|
227
|
+
"""
|
228
|
+
|
89
229
|
Scenario: Creating Events
|
90
230
|
Given there are no Events under topic "topic" in the database
|
91
231
|
When the client sends a POST request to "/v3/organization/events/topic" with no body
|
@@ -136,7 +276,7 @@ Feature: Events
|
|
136
276
|
}
|
137
277
|
"""
|
138
278
|
And there are no Events under topic "topic" in the database
|
139
|
-
|
279
|
+
|
140
280
|
Scenario: Deleting Events with a Time Query
|
141
281
|
Given the following Event exists under topic "topic" in the database:
|
142
282
|
"""
|
@@ -157,7 +297,7 @@ Feature: Events
|
|
157
297
|
When the client sends a DELETE request to "/v3/organization/events/topic" with the following body:
|
158
298
|
"""
|
159
299
|
{
|
160
|
-
"after": "2012-01-01T00:00:00.000Z"
|
300
|
+
"after": "2012-01-01T00:00:00.000Z"
|
161
301
|
}
|
162
302
|
"""
|
163
303
|
Then the response status should be 200
|
data/features/stashes.feature
CHANGED
@@ -49,21 +49,30 @@ Feature: Stashes
|
|
49
49
|
"""
|
50
50
|
{
|
51
51
|
"_id": "topic",
|
52
|
-
"root": {
|
52
|
+
"root": {
|
53
53
|
"b": 1
|
54
54
|
}
|
55
55
|
}
|
56
56
|
"""
|
57
|
+
And the following Stash exists in the database:
|
58
|
+
"""
|
59
|
+
{
|
60
|
+
"_id": "topic",
|
61
|
+
"root": {
|
62
|
+
"b": 5
|
63
|
+
}
|
64
|
+
}
|
65
|
+
"""
|
57
66
|
When the client sends a GET request to "/v3/organization/stashes" with the following body:
|
58
67
|
"""
|
59
|
-
{
|
60
|
-
"root.b": 1
|
68
|
+
{
|
69
|
+
"root.b": 1
|
61
70
|
}
|
62
71
|
"""
|
63
72
|
Then the response status should be 200
|
64
73
|
And the response body should be:
|
65
74
|
"""
|
66
|
-
[
|
75
|
+
[
|
67
76
|
{
|
68
77
|
"topic": "topic",
|
69
78
|
"root": {
|
@@ -88,7 +97,7 @@ Feature: Stashes
|
|
88
97
|
"""
|
89
98
|
When the client sends a GET request to "/v3/organization/stashes" with the following body:
|
90
99
|
"""
|
91
|
-
{
|
100
|
+
{
|
92
101
|
"root.b": 1,
|
93
102
|
"fields": ["root.a"]
|
94
103
|
}
|
@@ -108,6 +117,98 @@ Feature: Stashes
|
|
108
117
|
]
|
109
118
|
"""
|
110
119
|
|
120
|
+
Scenario: Retrieving Stashes using Sorting
|
121
|
+
Given the following Stash exists in the database:
|
122
|
+
"""
|
123
|
+
{
|
124
|
+
"_id": "topic1",
|
125
|
+
"root": {
|
126
|
+
"a": {
|
127
|
+
"foo": 3
|
128
|
+
},
|
129
|
+
"b": 1
|
130
|
+
}
|
131
|
+
}
|
132
|
+
"""
|
133
|
+
And the following Stash exists in the database:
|
134
|
+
"""
|
135
|
+
{
|
136
|
+
"_id": "topic2",
|
137
|
+
"root": {
|
138
|
+
"a": {
|
139
|
+
"foo": 2
|
140
|
+
},
|
141
|
+
"b": 1
|
142
|
+
}
|
143
|
+
}
|
144
|
+
"""
|
145
|
+
When the client sends a GET request to "/v3/organization/stashes" with the following body:
|
146
|
+
"""
|
147
|
+
{
|
148
|
+
"root.b": 1,
|
149
|
+
"sort": "root.a.foo",
|
150
|
+
"order": "asc"
|
151
|
+
}
|
152
|
+
"""
|
153
|
+
Then the response status should be 200
|
154
|
+
And the response body should be:
|
155
|
+
"""
|
156
|
+
[
|
157
|
+
{
|
158
|
+
"topic": "topic2",
|
159
|
+
"root": {
|
160
|
+
"a": {
|
161
|
+
"foo": 2
|
162
|
+
},
|
163
|
+
"b": 1
|
164
|
+
}
|
165
|
+
},
|
166
|
+
{
|
167
|
+
"topic": "topic1",
|
168
|
+
"root": {
|
169
|
+
"a": {
|
170
|
+
"foo": 3
|
171
|
+
},
|
172
|
+
"b": 1
|
173
|
+
}
|
174
|
+
}
|
175
|
+
]
|
176
|
+
"""
|
177
|
+
|
178
|
+
Scenario: Retrieving Stashes using Limits
|
179
|
+
Given the following Stash exists in the database:
|
180
|
+
"""
|
181
|
+
{
|
182
|
+
"_id": "topic1",
|
183
|
+
"b": 1
|
184
|
+
}
|
185
|
+
"""
|
186
|
+
And the following Stash exists in the database:
|
187
|
+
"""
|
188
|
+
{
|
189
|
+
"_id": "topic2",
|
190
|
+
"b": 1
|
191
|
+
}
|
192
|
+
"""
|
193
|
+
When the client sends a GET request to "/v3/organization/stashes" with the following body:
|
194
|
+
"""
|
195
|
+
{
|
196
|
+
"b": 1,
|
197
|
+
"limit": 1,
|
198
|
+
"order": "desc"
|
199
|
+
}
|
200
|
+
"""
|
201
|
+
Then the response status should be 200
|
202
|
+
And the response body should be:
|
203
|
+
"""
|
204
|
+
[
|
205
|
+
{
|
206
|
+
"topic": "topic2",
|
207
|
+
"b": 1
|
208
|
+
}
|
209
|
+
]
|
210
|
+
"""
|
211
|
+
|
111
212
|
Scenario: Creating Stashes without a Query
|
112
213
|
Given there are no matching Stashes in the database
|
113
214
|
When the client sends a POST request to "/v3/organization/stashes" with no body
|
data/lib/vayacondios.rb
CHANGED
@@ -29,9 +29,11 @@ module Vayacondios::Server
|
|
29
29
|
opts.separator ''
|
30
30
|
opts.separator 'Database options:'
|
31
31
|
|
32
|
-
options[
|
33
|
-
|
34
|
-
|
32
|
+
options[Goliath.env] ||= {}
|
33
|
+
options[Goliath.env][:database] ||= {}
|
34
|
+
db_options = options[Goliath.env][:database]
|
35
|
+
|
36
|
+
defaults = DbConfig.defaults[Goliath.env][:database]
|
35
37
|
opts.on('-d', '--database.driver NAME', "Database driver (default: #{defaults[:driver]})") do |name|
|
36
38
|
db_options[:driver] = name
|
37
39
|
end
|
@@ -2,22 +2,24 @@ module Vayacondios::Server
|
|
2
2
|
class Configuration < Vayacondios::Configuration
|
3
3
|
|
4
4
|
def defaults
|
5
|
-
{
|
6
|
-
|
5
|
+
%w[development test production].inject({}) do |default_conf, type|
|
6
|
+
default_conf[type.to_sym] = {}
|
7
|
+
default_conf[type.to_sym][:database] = {
|
7
8
|
driver: 'mongo',
|
8
9
|
host: 'localhost',
|
9
10
|
port: 27017,
|
10
|
-
name:
|
11
|
+
name: "vayacondios_#{type}",
|
11
12
|
connections: 20,
|
12
13
|
}
|
13
|
-
|
14
|
+
default_conf
|
15
|
+
end
|
14
16
|
end
|
15
17
|
|
16
18
|
def env(handle = nil)
|
17
19
|
handle ||= :development
|
18
20
|
resolved_settings[handle.to_sym] || {}
|
19
|
-
end
|
21
|
+
end
|
20
22
|
end
|
21
|
-
|
23
|
+
|
22
24
|
DbConfig = Configuration.new('database.yml') unless defined? DbConfig
|
23
25
|
end
|
@@ -50,10 +50,8 @@ module Vayacondios::Server
|
|
50
50
|
sel = { }.tap do |sel|
|
51
51
|
time = query.delete(:_t)
|
52
52
|
sel[:_t] = time.inject({}){ |t, (k,v)| t[('$' + k.to_s).to_sym] = v ; t } if time
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
query.merge(sel).compact_blank
|
53
|
+
sel.merge! to_dotted_hash(query)
|
54
|
+
end.compact_blank
|
57
55
|
end
|
58
56
|
|
59
57
|
def to_dotted_hash(hsh, key_string = '')
|
@@ -66,14 +64,19 @@ module Vayacondios::Server
|
|
66
64
|
end
|
67
65
|
end
|
68
66
|
end
|
69
|
-
|
67
|
+
|
70
68
|
def projector query
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
69
|
+
order = query.delete(:order)
|
70
|
+
if order.to_s.match(/^(a|de)sc$/i)
|
71
|
+
order = order.to_sym
|
72
|
+
else
|
73
|
+
raise Error.new("Search order must be 'asc' or 'desc'. Invalid search order: #{order}")
|
75
74
|
end
|
76
|
-
|
75
|
+
|
76
|
+
fields = query[:fields]
|
77
|
+
fields.map!{|field| field.join('.') } if fields.is_a? Array
|
78
|
+
|
79
|
+
query[:sort] = [query[:sort].join('.'), order]
|
77
80
|
query
|
78
81
|
end
|
79
82
|
|
@@ -30,7 +30,7 @@ module Vayacondios::Server
|
|
30
30
|
def format_response result
|
31
31
|
from_document(result.symbolize_keys.compact).external_document
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# A class for errors that arise within documents due to internal or
|
35
35
|
# IO errors.
|
36
36
|
Error = Class.new(StandardError)
|
@@ -54,7 +54,15 @@ module Vayacondios::Server
|
|
54
54
|
params.symbolize_keys!
|
55
55
|
opts = {}
|
56
56
|
[:limit, :order, :sort, :fields].each{ |opt| opts[opt] = params.delete opt }
|
57
|
-
opts.
|
57
|
+
default_query_options.dup.merge(opts.compact).tap do |opts|
|
58
|
+
opts[:sort] = opts[:sort].to_s.split('.')
|
59
|
+
if opts[:fields].is_a? Array
|
60
|
+
opts[:fields].map!{|field|
|
61
|
+
field = '_id' if field == 'id'
|
62
|
+
field.split('.')
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
58
66
|
end
|
59
67
|
|
60
68
|
def search(params, query, &driver)
|
@@ -63,7 +71,7 @@ module Vayacondios::Server
|
|
63
71
|
result = driver.call(action, action.filter, options)
|
64
72
|
result.map{ |res| new.format_response res }
|
65
73
|
end
|
66
|
-
|
74
|
+
|
67
75
|
def create(params, document, &driver)
|
68
76
|
action = receive(params).prepare_create(document)
|
69
77
|
result = driver.call(action)
|
@@ -76,7 +84,7 @@ module Vayacondios::Server
|
|
76
84
|
return nil if result.nil?
|
77
85
|
action.format_response result
|
78
86
|
end
|
79
|
-
|
87
|
+
|
80
88
|
def destroy(params, document, &driver)
|
81
89
|
action = receive(params).prepare_destroy(document.symbolize_keys)
|
82
90
|
result = driver.call(action, action.filter)
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# POST /v2/coca_cola/event/ad_campaigns
|
11
11
|
# { "impresions": 23829, "errors": 29 }
|
12
12
|
# ```
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# would result in a document in the `coca_cola.ad_campaigns.events`
|
15
15
|
# collection with the following structure:
|
16
16
|
#
|
@@ -53,9 +53,9 @@ module Vayacondios::Server
|
|
53
53
|
|
54
54
|
# The default number of events returned when searching.
|
55
55
|
LIMIT = 50
|
56
|
-
|
56
|
+
|
57
57
|
# The default sort order when searching
|
58
|
-
ORDER = '
|
58
|
+
ORDER = 'desc'
|
59
59
|
|
60
60
|
# The default sort field when searching.
|
61
61
|
SORT = 'time'
|
@@ -65,7 +65,21 @@ module Vayacondios::Server
|
|
65
65
|
WINDOW = 3600
|
66
66
|
|
67
67
|
def self.default_query_options
|
68
|
-
{ limit: LIMIT, order: ORDER, sort: SORT }
|
68
|
+
{ limit: LIMIT, order: ORDER, sort: SORT }
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.extract_query_options! opts
|
72
|
+
query = super
|
73
|
+
if query[:sort] == ['time']
|
74
|
+
query[:sort] = ['_t']
|
75
|
+
elsif query[:sort].present?
|
76
|
+
query[:sort].unshift '_d'
|
77
|
+
end
|
78
|
+
query[:fields].each{|field|
|
79
|
+
field.replace(['_t']) if field == ['time']
|
80
|
+
field.unshift('_d') unless %w[_id _t].include?(field.first)
|
81
|
+
} if query[:fields].present?
|
82
|
+
query
|
69
83
|
end
|
70
84
|
|
71
85
|
field :time, Time # assigned or Time.now.utc
|
@@ -84,14 +98,14 @@ module Vayacondios::Server
|
|
84
98
|
@time = format_time to_timestamp(t)
|
85
99
|
end
|
86
100
|
|
87
|
-
# Parses an object into a timestamp.
|
101
|
+
# Parses an object into a timestamp.
|
88
102
|
#
|
89
103
|
# @param [String, Numeric, Time, nil] obj
|
90
104
|
# @param [Time] default the time value to return if none could be found in the `obj`
|
91
105
|
# @return [Time]
|
92
106
|
def to_timestamp(obj, default = Time.now)
|
93
107
|
case obj
|
94
|
-
when String then Time.parse(obj)
|
108
|
+
when String then Time.parse(obj)
|
95
109
|
when Date then obj.to_time
|
96
110
|
when Time then obj
|
97
111
|
when Numeric then Time.at(obj)
|
@@ -130,7 +144,7 @@ module Vayacondios::Server
|
|
130
144
|
|
131
145
|
# An event as presented to a user
|
132
146
|
def external_document
|
133
|
-
{ id: id, time: time.iso8601(3) }.merge(body)
|
147
|
+
{ id: id, time: (time ? time.iso8601(3) : nil) }.merge(body).compact
|
134
148
|
end
|
135
149
|
|
136
150
|
# Returns a Hash that can be used for selection criteria in a query
|
@@ -193,6 +207,6 @@ module Vayacondios::Server
|
|
193
207
|
def prepare_destroy query
|
194
208
|
receive!(filter: event_filter(query))
|
195
209
|
self
|
196
|
-
end
|
210
|
+
end
|
197
211
|
end
|
198
212
|
end
|
@@ -25,15 +25,15 @@ module Vayacondios::Server
|
|
25
25
|
LIMIT = 50
|
26
26
|
|
27
27
|
# The default sort order when searching.
|
28
|
-
SORT = '
|
29
|
-
ORDER = '
|
28
|
+
SORT = '_id'
|
29
|
+
ORDER = 'asc'
|
30
30
|
|
31
31
|
# Returned as an acknowledgement of the request when there is no
|
32
32
|
# better option (#destroy, #update_many, &c.)
|
33
33
|
# OK = {ok: true}
|
34
34
|
|
35
35
|
def self.default_query_options
|
36
|
-
{ limit: LIMIT, order: ORDER, sort: SORT }
|
36
|
+
{ limit: LIMIT, order: ORDER, sort: SORT }
|
37
37
|
end
|
38
38
|
|
39
39
|
# The name of the collection this stash will store its data in.
|
@@ -52,16 +52,16 @@ module Vayacondios::Server
|
|
52
52
|
d[:topic] = doc.delete(:_id)
|
53
53
|
doc = nil if doc.empty?
|
54
54
|
if body.nil?
|
55
|
-
new_body = doc
|
55
|
+
new_body = doc
|
56
56
|
else
|
57
57
|
new_body = body.merge(doc || {})
|
58
|
-
end
|
58
|
+
end
|
59
59
|
d[:body] = new_body
|
60
60
|
end
|
61
61
|
receive! d
|
62
62
|
self
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def external_document
|
66
66
|
{ topic: topic }.merge(body || {})
|
67
67
|
end
|
@@ -76,7 +76,7 @@ module Vayacondios::Server
|
|
76
76
|
if document.is_a? Hash
|
77
77
|
document.symbolize_keys!
|
78
78
|
raise Error.new ':topic is a reserved key and cannot be used in a stash document' if document.has_key?(:topic)
|
79
|
-
end
|
79
|
+
end
|
80
80
|
if id.blank?
|
81
81
|
raise Error.new 'If not including an Id, the document must be a Hash' unless document.is_a? Hash
|
82
82
|
receive!(body: document)
|
@@ -23,7 +23,7 @@ describe Vayacondios::Server::ApiOptions do
|
|
23
23
|
ARGV.replace %w[-d foo -h foo.com -D bar -o 1234 -n 10]
|
24
24
|
api.options_parser(parser, settings)
|
25
25
|
parser.parse!
|
26
|
-
settings[:database].should eq(driver: 'foo',
|
26
|
+
settings[:test][:database].should eq(driver: 'foo',
|
27
27
|
connections: 10,
|
28
28
|
host: 'foo.com',
|
29
29
|
name: 'bar',
|
@@ -3,11 +3,31 @@ require 'spec_helper'
|
|
3
3
|
describe Vayacondios::Server::Configuration do
|
4
4
|
its(:defaults) do
|
5
5
|
should eq(development: {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
database: {
|
7
|
+
driver: 'mongo',
|
8
|
+
host: 'localhost',
|
9
|
+
port: 27017,
|
10
|
+
name: 'vayacondios_development',
|
11
|
+
connections: 20,
|
12
|
+
}
|
13
|
+
},
|
14
|
+
test: {
|
15
|
+
database: {
|
16
|
+
driver: 'mongo',
|
17
|
+
host: 'localhost',
|
18
|
+
port: 27017,
|
19
|
+
name: 'vayacondios_test',
|
20
|
+
connections: 20,
|
21
|
+
}
|
22
|
+
},
|
23
|
+
production: {
|
24
|
+
database: {
|
25
|
+
driver: 'mongo',
|
26
|
+
host: 'localhost',
|
27
|
+
port: 27017,
|
28
|
+
name: 'vayacondios_production',
|
29
|
+
connections: 20,
|
30
|
+
}
|
11
31
|
})
|
12
32
|
end
|
13
33
|
|
@@ -17,11 +37,12 @@ describe Vayacondios::Server::Configuration do
|
|
17
37
|
|
18
38
|
context '#env' do
|
19
39
|
it 'allows hash access scoped by environment' do
|
20
|
-
subject.env(:development).should eq(
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
40
|
+
subject.env(:development).should eq(database: {
|
41
|
+
driver: 'mongo',
|
42
|
+
host: 'localhost',
|
43
|
+
port: 27017,
|
44
|
+
name: 'vayacondios_development',
|
45
|
+
connections: 20 })
|
25
46
|
end
|
26
47
|
end
|
27
48
|
end
|
@@ -1,9 +1,56 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Vayacondios::Server::Document do
|
4
|
-
|
5
|
-
let(:params){ { organization: 'organization', topic: 'topic' } }
|
6
4
|
|
7
|
-
|
5
|
+
let(:params){ {
|
6
|
+
organization: 'organization',
|
7
|
+
topic: 'topic',
|
8
|
+
order: 'ascending',
|
9
|
+
sort: 'hostname.internal',
|
10
|
+
fields: ['id', 'hostname.internal']
|
11
|
+
} }
|
12
|
+
|
13
|
+
subject(:document){ described_class.receive(params) }
|
14
|
+
|
15
|
+
context '.extract_query_options!' do
|
16
|
+
let(:model) do
|
17
|
+
klass = Class.new(document.class) do
|
18
|
+
def self.default_query_options
|
19
|
+
{ limit: 5, order: 'descending', sort: 'time' }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:options) do
|
25
|
+
model.extract_query_options! params
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'removes projection params' do
|
29
|
+
options.should have_key :limit
|
30
|
+
options.should have_key :sort
|
31
|
+
options.should have_key :order
|
32
|
+
|
33
|
+
params.should_not have_key :limit
|
34
|
+
params.should_not have_key :sort
|
35
|
+
params.should_not have_key :order
|
36
|
+
|
37
|
+
params.should have_key :organization
|
38
|
+
params.should have_key :topic
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'uses defaults' do
|
42
|
+
options.should have_key :sort
|
43
|
+
options[:limit].should eq 5
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'uses params when provided' do
|
47
|
+
options.should have_key :limit
|
48
|
+
options.should have_key :order
|
49
|
+
|
50
|
+
options[:sort].should eq ['hostname', 'internal']
|
51
|
+
options[:fields].should eq [['_id'], ['hostname', 'internal']]
|
52
|
+
options[:order].should eq 'ascending'
|
53
|
+
end
|
54
|
+
end
|
8
55
|
|
9
56
|
end
|
data/vayacondios-server.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_dependency('configliere', '>= 0.4.16')
|
22
22
|
gem.add_dependency('gorillib', '>= 0.4.2')
|
23
23
|
gem.add_dependency('multi_json', '>= 1.3.6')
|
24
|
-
gem.add_dependency('goliath-chimp', '>= 0.0.
|
24
|
+
gem.add_dependency('goliath-chimp', '>= 0.0.3')
|
25
25
|
|
26
26
|
gem.add_dependency('eventmachine', '~> 1.0')
|
27
27
|
gem.add_dependency('goliath', '~> 1.0')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vayacondios-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-
|
15
|
+
date: 2014-03-11 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: configliere
|
@@ -69,7 +69,7 @@ dependencies:
|
|
69
69
|
requirements:
|
70
70
|
- - ! '>='
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version: 0.0.
|
72
|
+
version: 0.0.3
|
73
73
|
type: :runtime
|
74
74
|
prerelease: false
|
75
75
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -77,7 +77,7 @@ dependencies:
|
|
77
77
|
requirements:
|
78
78
|
- - ! '>='
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: 0.0.
|
80
|
+
version: 0.0.3
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: eventmachine
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -251,7 +251,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
251
251
|
version: '0'
|
252
252
|
segments:
|
253
253
|
- 0
|
254
|
-
hash:
|
254
|
+
hash: -1277258498442787077
|
255
255
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
256
256
|
none: false
|
257
257
|
requirements:
|
@@ -260,7 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
260
260
|
version: '0'
|
261
261
|
segments:
|
262
262
|
- 0
|
263
|
-
hash:
|
263
|
+
hash: -1277258498442787077
|
264
264
|
requirements: []
|
265
265
|
rubyforge_project:
|
266
266
|
rubygems_version: 1.8.23
|