orchestrate 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/README.md +28 -20
- data/lib/orchestrate/api/errors.rb +114 -52
- data/lib/orchestrate/api/helpers.rb +48 -0
- data/lib/orchestrate/api/response.rb +111 -0
- data/lib/orchestrate/api.rb +4 -6
- data/lib/orchestrate/client.rb +290 -302
- data/lib/orchestrate/version.rb +1 -1
- data/lib/orchestrate.rb +0 -37
- data/test/orchestrate/api/collections_test.rb +28 -6
- data/test/orchestrate/api/event_test.rb +85 -20
- data/test/orchestrate/api/exceptions_test.rb +172 -0
- data/test/orchestrate/api/graph_test.rb +4 -0
- data/test/orchestrate/api/key_value_test.rb +52 -7
- data/test/orchestrate/api/response_test.rb +36 -0
- data/test/orchestrate/client_test.rb +15 -16
- data/test/test_helper.rb +4 -9
- metadata +10 -6
- data/lib/orchestrate/configuration.rb +0 -53
- data/lib/orchestrate/helpers.rb +0 -22
- data/test/orchestrate/configuration_test.rb +0 -67
data/lib/orchestrate/client.rb
CHANGED
@@ -3,359 +3,346 @@ require 'faraday_middleware'
|
|
3
3
|
|
4
4
|
module Orchestrate
|
5
5
|
|
6
|
-
# ==== Ruby Client for the Orchestrate REST *API*.
|
7
|
-
#
|
8
|
-
# The primary entry point is the #send_request method, which generates a
|
9
|
-
# Request, and returns the Response to the caller.
|
10
|
-
#
|
11
6
|
class Client
|
12
7
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
8
|
+
# @return [String] The API key provided
|
9
|
+
attr_reader :api_key
|
10
|
+
|
11
|
+
# @return [Faraday::Connection] The Faraday HTTP connection.
|
12
|
+
attr_reader :http
|
13
|
+
|
14
|
+
# @return [Proc] The block used to configure faraday.
|
15
|
+
attr_reader :faraday_configuration
|
16
|
+
|
17
|
+
# Instantiate a new Client for an Orchestrate application.
|
18
|
+
# @param api_key [#to_s] The API Key for your Orchestrate application.
|
19
|
+
# @yieldparam [Faraday::Connection] The setup for the faraday connection.
|
20
|
+
# @return Orchestrate::Client
|
21
|
+
# @todo api_key -> app_url, parse api_key from auth section of url
|
22
|
+
def initialize(api_key, &block)
|
23
|
+
@api_key = api_key
|
24
|
+
@faraday_configuration = block
|
25
|
+
@http = Faraday.new("https://api.orchestrate.io") do |faraday|
|
26
|
+
block = lambda{|f| f.adapter Faraday.default_adapter } unless block
|
27
|
+
block.call faraday
|
33
28
|
|
34
29
|
# faraday seems to want you do specify these twice.
|
35
|
-
faraday.request :basic_auth,
|
36
|
-
faraday.basic_auth
|
30
|
+
faraday.request :basic_auth, api_key, ''
|
31
|
+
faraday.basic_auth api_key, ''
|
37
32
|
|
38
33
|
# parses JSON responses
|
39
34
|
faraday.response :json, :content_type => /\bjson$/
|
40
35
|
end
|
41
36
|
end
|
42
37
|
|
43
|
-
#
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
#
|
49
|
-
# Performes a List query against the given collection. Results are sorted
|
50
|
-
# lexicographically by key name.
|
51
|
-
#
|
52
|
-
# +collection_name+:: A String or Symbol representing the name of the collection.
|
53
|
-
# +parameters+:: a Hash object containing query parameters:
|
54
|
-
# - +:limit+ - integer, number of results to return. Defaults to 10, Max 100.
|
55
|
-
# - +:start+ - string, start key of query range, including value.
|
56
|
-
# - +:after+ - string, start key of query range, excluding value.
|
57
|
-
# - +:before+ - string, end key of query range, excluding value.
|
58
|
-
# - +:end+ - string, end key of query range, including value.
|
59
|
-
#
|
60
|
-
# Note, you cannot provide *both* 'start' and 'after', or 'before' and 'end'
|
61
|
-
#
|
62
|
-
def list(collection, options={})
|
63
|
-
Orchestrate::Helpers.range_keys!('key', options)
|
64
|
-
send_request :get, [collection], { query: options }
|
38
|
+
# Tests authentication with Orchestrate.
|
39
|
+
# @return Orchestrate::API::Response
|
40
|
+
# @raise Orchestrate::API::Unauthorized if the client could not authenticate.
|
41
|
+
def ping
|
42
|
+
send_request :get, []
|
65
43
|
end
|
66
44
|
|
67
|
-
#
|
68
|
-
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
79
|
-
|
45
|
+
# @!group Collections
|
46
|
+
|
47
|
+
# [Search the items in
|
48
|
+
# a collection](http://orchestrate.io/docs/api/#search) using a Lucene
|
49
|
+
# Query Syntax.
|
50
|
+
# @param collection [#to_s] The name of the collection
|
51
|
+
# @param query [String] The [Lucene Query String][lucene] to query the collection with.
|
52
|
+
# [lucene]: http://lucene.apache.org/core/4_3_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Overview
|
53
|
+
# @param options [Hash] Parameters for the query
|
54
|
+
# @option options [Integer] :limit (10) The number of results to return. Maximum 100.
|
55
|
+
# @option options [Integer] :offset (0) The starting position of the results.
|
56
|
+
# @return Orchestrate::API::CollectionResponse
|
57
|
+
# @raise Orchestrate::API::InvalidSearchParam The :limit/:offset values are not valid.
|
58
|
+
# @raise Orchestrate::API::SearchQueryMalformed if query isn't a valid Lucene query.
|
59
|
+
def search(collection, query, options={})
|
60
|
+
send_request :get, [collection], { query: options.merge({query: query}),
|
61
|
+
response: API::CollectionResponse }
|
80
62
|
end
|
81
63
|
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
# +collection_name+:: a String or Symbol representing the name of the collection.
|
88
|
-
#
|
64
|
+
# [Deletes an entire collection](http://orchestrate.io/docs/api/#collections/delete)
|
65
|
+
# @param collection [#to_s] The name of the collection
|
66
|
+
# @return Orchestrate::API::Response
|
67
|
+
# @note The Orchestrate API will return succesfully regardless of if the collection exists or not.
|
89
68
|
def delete_collection(collection)
|
90
69
|
send_request :delete, [collection], { query: {force:true} }
|
91
70
|
end
|
92
71
|
|
93
|
-
#
|
94
|
-
#
|
95
|
-
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
72
|
+
# @!endgroup
|
73
|
+
# @!group Key/Value
|
74
|
+
|
75
|
+
# [Retrieves the value assigned to a key](http://orchestrate.io/docs/api/#key/value/get).
|
76
|
+
# If a `ref` parameter is provided, [retrieves a historical value for the
|
77
|
+
# key](http://orchestrate.io/docs/api/#refs/get14)
|
78
|
+
# @param collection [#to_s] The name of the collection.
|
79
|
+
# @param key [#to_s] The name of the key.
|
80
|
+
# @param ref [#to_s] The opaque version identifier of the ref to return, if a historical value is desired.
|
81
|
+
# @return Orchestrate::API::ItemResponse
|
82
|
+
# @raise Orchestrate::API::NotFound If the key or ref doesn't exist.
|
83
|
+
# @raise Orchestrate::API::MalformedRef If the ref provided is not a valid ref.
|
106
84
|
def get(collection, key, ref=nil)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
send_request :get, [collection, key]
|
111
|
-
end
|
85
|
+
path = [collection, key]
|
86
|
+
path.concat(['refs', ref]) if ref
|
87
|
+
send_request :get, path, { response: API::ItemResponse }
|
112
88
|
end
|
113
89
|
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
90
|
+
# [List historical refs for values of a key](http://orchestrate.io/docs/api/#refs/list15).
|
91
|
+
# Results are time-ordered newest-to-oldest and paginated.
|
92
|
+
# @param collection [#to_s] The name of the collection.
|
93
|
+
# @param key [#to_s] The name of the key.
|
94
|
+
# @param options [Hash] Parameters for the query.
|
95
|
+
# @option options [Integer] :limit (10) The number of results to return. Maximum 100.
|
96
|
+
# @option options [Integer] :offset (0) The starting position of the results.
|
97
|
+
# @option options [true, false] :values (false) Whether to return the value
|
98
|
+
# for each ref. Refs with no content (for example, deleted with `#delete`) will not have
|
99
|
+
# a value, but marked with a `'tombstone' => true` key.
|
100
|
+
# @return Orchestrate::API::CollectionResponse
|
101
|
+
# @raise Orchestrate::API::NotFound If there are no values for the provided key/collection.
|
102
|
+
# @raise Orchestrate::API::InvalidSearchParam The :limit/:offset values are not valid.
|
103
|
+
# @raise Orchestrate::API::MalformedRef If the ref provided is not a valid ref.
|
104
|
+
def list_refs(collection, key, options={})
|
105
|
+
send_request :get, [collection, key, :refs], { query: options, response: API::CollectionResponse }
|
106
|
+
end
|
107
|
+
|
108
|
+
# [Updates the value associated with
|
109
|
+
# a key](http://orchestrate.io/docs/api/#key/value/put-\(create/update\)).
|
110
|
+
# If the key does not currently have a value, will create the value.
|
111
|
+
# @param collection [#to_s] The name of the collection.
|
112
|
+
# @param key [#to_s] The name of the key.
|
113
|
+
# @param body [#to_json] The value for the key.
|
114
|
+
# @param condition [String, false, nil] Conditions for setting the value.
|
115
|
+
# If `String`, value used as `If-Match`, value will only be updated if key's current value's ref matches.
|
116
|
+
# If `false`, uses `If-None-Match` the value will only be set if there is no existent value for the key.
|
117
|
+
# If `nil` (default), value is set regardless.
|
118
|
+
# @return Orchestrate::API::ItemResponse
|
119
|
+
# @raise Orchestrate::API::BadRequest the body is not valid JSON.
|
120
|
+
# @raise Orchestrate::API::IndexingConflict One of the value's keys
|
121
|
+
# contains a value of a different type than the schema that exists for
|
122
|
+
# the collection.
|
123
|
+
# @see Orchestrate::API::IndexingConflict
|
124
|
+
# @raise Orchestrate::API::VersionMismatch A ref was provided, but it does not match the ref for the current value.
|
125
|
+
# @raise Orchestrate::API::AlreadyPresent the `false` condition was given, but a value already exists for this collection/key combo.
|
128
126
|
def put(collection, key, body, condition=nil)
|
129
127
|
headers={}
|
130
128
|
if condition.is_a?(String)
|
131
|
-
headers['If-Match'] = format_ref(condition)
|
129
|
+
headers['If-Match'] = API::Helpers.format_ref(condition)
|
132
130
|
elsif condition == false
|
133
131
|
headers['If-None-Match'] = '*'
|
134
132
|
end
|
135
|
-
send_request :put, [collection, key], { body: body, headers: headers }
|
133
|
+
send_request :put, [collection, key], { body: body, headers: headers, response: API::ItemResponse }
|
136
134
|
end
|
137
135
|
alias :put_if_unmodified :put
|
138
136
|
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
# Will create the value at the specified key only if there is no existing value for the specified key.
|
143
|
-
#
|
137
|
+
# [Creates the value for a key if none
|
138
|
+
# exists](http://orchestrate.io/docs/api/#key/value/put-\(create/update\)).
|
139
|
+
# @see #put
|
144
140
|
def put_if_absent(collection, key, body)
|
145
141
|
put collection, key, body, false
|
146
142
|
end
|
147
143
|
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
# +ref+:: if provided, used as 'If-Match', will only delete the key if the current value is the provided ref.
|
157
|
-
#
|
144
|
+
# [Sets the current value of a key to a null
|
145
|
+
# object](http://orchestrate.io/docs/api/#key/value/delete11).
|
146
|
+
# @param collection [#to_s] The name of the collection.
|
147
|
+
# @param key [#to_s] The name of the key.
|
148
|
+
# @param ref [#to_s] If specified, deletes the ref only if the current value's ref matches.
|
149
|
+
# @return Orchestrate::API::Response
|
150
|
+
# @raise Orchestrate::API::VersionMismatch if the provided ref is not the ref for the current value.
|
151
|
+
# @note previous versions of the values at this key are still available via #list_refs and #get.
|
158
152
|
def delete(collection, key, ref=nil)
|
159
153
|
headers = {}
|
160
|
-
headers['If-Match'] = format_ref(ref) if ref
|
154
|
+
headers['If-Match'] = API::Helpers.format_ref(ref) if ref
|
161
155
|
send_request :delete, [collection, key], { headers: headers }
|
162
156
|
end
|
163
157
|
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
170
|
-
# +key+:: a String or Symbol representing the key for the value.
|
171
|
-
#
|
158
|
+
# [Purges the current value and ref history associated with the
|
159
|
+
# key](http://orchestrate.io/docs/api/#key/value/delete11).
|
160
|
+
# @param collection [#to_s] The name of the collection.
|
161
|
+
# @param key [#to_s] The name of the key.
|
162
|
+
# @return Orchestrate::API::Response
|
163
|
+
# @todo take an optional ref for If-Match
|
172
164
|
def purge(collection, key)
|
173
165
|
send_request :delete, [collection, key], { query: { purge: true } }
|
174
166
|
end
|
175
167
|
|
176
|
-
#
|
177
|
-
#
|
178
|
-
|
179
|
-
#
|
180
|
-
#
|
181
|
-
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
#
|
185
|
-
#
|
186
|
-
#
|
187
|
-
#
|
188
|
-
#
|
189
|
-
#
|
190
|
-
|
191
|
-
|
192
|
-
|
168
|
+
# [List the KeyValue items in a collection](http://orchestrate.io/docs/api/#key/value/list).
|
169
|
+
# Results are sorted results lexicographically by key name and paginated.
|
170
|
+
# @param collection [#to_s] The name of the collection
|
171
|
+
# @param options [Hash] Parameters for the query
|
172
|
+
# @option options [Integer] :limit (10) The number of results to return. Maximum 100.
|
173
|
+
# @option options [String] :start The inclusive start key of the query range.
|
174
|
+
# @option options [String] :after The exclusive start key of the query range.
|
175
|
+
# @option options [String] :before The exclusive end key of the query range.
|
176
|
+
# @option options [String] :end The inclusive end key of the query range.
|
177
|
+
# @note The Orchestrate API may return an error if you include both the
|
178
|
+
# :start/:after or :before/:end keys. The client will not stop you from doing this.
|
179
|
+
# @note To include all keys in a collection, do not include any :start/:after/:before/:end parameters.
|
180
|
+
# @return Orchestrate::API::CollectionResponse
|
181
|
+
# @raise Orchestrate::API::InvalidSearchParam The :limit value is not valid.
|
182
|
+
def list(collection, options={})
|
183
|
+
API::Helpers.range_keys!('key', options)
|
184
|
+
send_request :get, [collection], { query: options, response: API::CollectionResponse }
|
185
|
+
end
|
186
|
+
|
187
|
+
# @!endgroup
|
188
|
+
# @!group Events
|
189
|
+
|
190
|
+
# [Retrieves an individual event](http://orchestrate.io/docs/api/#events/get19).
|
191
|
+
# @param collection [#to_s] The name of the collection.
|
192
|
+
# @param key [#to_s] The name of the key.
|
193
|
+
# @param event_type [#to_s] The category for the event.
|
194
|
+
# @param timestamp [Time, Date, Integer, String] The timestamp for the event.
|
195
|
+
# If a String, must match the [Timestamp specification](http://orchestrate.io/docs/api/#events/timestamps)
|
196
|
+
# and include the milliseconds portion.
|
197
|
+
# @param ordinal [Integer, #to_s] The ordinal for the event in the given timestamp.
|
198
|
+
# @return Orchestrate::API::ItemResponse
|
199
|
+
# @raise Orchestrate::API::NotFound If the requested event doesn't exist.
|
193
200
|
def get_event(collection, key, event_type, timestamp, ordinal)
|
194
|
-
|
201
|
+
timestamp = API::Helpers.timestamp(timestamp)
|
202
|
+
path = [collection, key, 'events', event_type, timestamp, ordinal]
|
203
|
+
send_request :get, path, { response: API::ItemResponse }
|
195
204
|
end
|
196
205
|
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
# +timestamp+:: an Integer or String representing a time.
|
208
|
-
# - nil - Timestamp value will be created by Orchestrate.
|
209
|
-
# - Integers are Milliseconds since Unix Epoch.
|
210
|
-
# - Strings must be formatted as per http://orchestrate.io/docs/api/#events/timestamps
|
211
|
-
# - A future version will support ruby Time objects.
|
212
|
-
#
|
206
|
+
# [Creates an event](http://orchestrate.io/docs/api/#events/post-\(create\)).
|
207
|
+
# @param collection [#to_s] The name of the collection.
|
208
|
+
# @param key [#to_s] The name of the key.
|
209
|
+
# @param event_type [#to_s] The category for the event.
|
210
|
+
# @param body [#to_json] The value for the event.
|
211
|
+
# @param timestamp [Time, Date, Integer, String, nil] The timestamp for the event.
|
212
|
+
# If omitted, the timestamp is created by Orchestrate.
|
213
|
+
# If a String, must match the [Timestamp specification](http://orchestrate.io/docs/api/#events/timestamps).
|
214
|
+
# @return Orchestrate::API::ItemResponse
|
215
|
+
# @raise Orchestrate::API::BadRequest If the body is not valid JSON.
|
213
216
|
def post_event(collection, key, event_type, body, timestamp=nil)
|
217
|
+
timestamp = API::Helpers.timestamp(timestamp)
|
214
218
|
path = [collection, key, 'events', event_type, timestamp].compact
|
215
|
-
send_request :post, path, { body: body }
|
219
|
+
send_request :post, path, { body: body, response: API::ItemResponse }
|
216
220
|
end
|
217
221
|
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
#
|
234
|
-
#
|
235
|
-
# - String - used as 'If-Match'. The event will only update if the event's current value matches this ref.
|
236
|
-
#
|
222
|
+
# [Updates an existing event](http://orchestrate.io/docs/api/#events/put-\(update\)).
|
223
|
+
# @param collection [#to_s] The name of the collection.
|
224
|
+
# @param key [#to_s] The name of the key.
|
225
|
+
# @param event_type [#to_s] The category for the event.
|
226
|
+
# @param timestamp [Time, Date, Integer, String, nil] The timestamp for the event.
|
227
|
+
# If a String, must match the [Timestamp specification](http://orchestrate.io/docs/api/#events/timestamps)
|
228
|
+
# and include the milliseconds portion.
|
229
|
+
# @param ordinal [Integer, #to_s] The ordinal for the event in the given timestamp.
|
230
|
+
# @param body [#to_json] The value for the event.
|
231
|
+
# @param ref [nil, #to_s] If provided, used as `If-Match`, and event will
|
232
|
+
# only update if its current value has the provided ref. If omitted,
|
233
|
+
# updates the event regardless.
|
234
|
+
# @return Orchestrate::API::ItemResponse
|
235
|
+
# @raise Orchestrate::API::NotFound The specified event doesn't exist.
|
236
|
+
# @raise Orchestrate::API::BadRequest If the body is not valid JSON.
|
237
|
+
# @raise Orchestrate::API::VersionMismatch The event's current value has a ref that does not match the provided ref.
|
238
|
+
# @raise Orchestrate::API::MalformedRef If the ref provided is not a valid ref.
|
237
239
|
def put_event(collection, key, event_type, timestamp, ordinal, body, ref=nil)
|
240
|
+
timestamp = API::Helpers.timestamp(timestamp)
|
238
241
|
path = [collection, key, 'events', event_type, timestamp, ordinal]
|
239
242
|
headers = {}
|
240
|
-
headers['If-Match'] = format_ref(ref) if ref
|
241
|
-
send_request :put, path, { body: body, headers: headers }
|
243
|
+
headers['If-Match'] = API::Helpers.format_ref(ref) if ref
|
244
|
+
send_request :put, path, { body: body, headers: headers, response: API::ItemResponse }
|
242
245
|
end
|
243
246
|
|
244
|
-
#
|
245
|
-
#
|
246
|
-
#
|
247
|
-
#
|
248
|
-
#
|
249
|
-
#
|
250
|
-
#
|
251
|
-
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
#
|
257
|
-
#
|
258
|
-
# +ref+::
|
259
|
-
# - +nil+ - The event will be deleted regardless.
|
260
|
-
# - String - used as 'If-Match'. The event will only be deleted if the event's current value matches this ref.
|
261
|
-
#
|
247
|
+
# [Deletes an existing event](http://orchestrate.io/docs/api/#events/delete22).
|
248
|
+
# @param collection [#to_s] The name of the collection.
|
249
|
+
# @param key [#to_s] The name of the key.
|
250
|
+
# @param event_type [#to_s] The category for the event.
|
251
|
+
# @param timestamp [Time, Date, Integer, String, nil] The timestamp for the event.
|
252
|
+
# If a String, must match the [Timestamp specification](http://orchestrate.io/docs/api/#events/timestamps)
|
253
|
+
# and include the milliseconds portion.
|
254
|
+
# @param ordinal [Integer, #to_s] The ordinal for the event in the given timestamp.
|
255
|
+
# @param ref [nil, #to_s] If provided, used as `If-Match`, and event will
|
256
|
+
# only update if its current value has the provided ref. If omitted,
|
257
|
+
# updates the event regardless.
|
258
|
+
# @return Orchestrate::API::Response
|
259
|
+
# @raise Orchestrate::API::VersionMismatch The event's current value has a ref that does not match the provided ref.
|
260
|
+
# @raise Orchestrate::API::MalformedRef If the ref provided is not a valid ref.
|
262
261
|
def purge_event(collection, key, event_type, timestamp, ordinal, ref=nil)
|
262
|
+
timestamp = API::Helpers.timestamp(timestamp)
|
263
263
|
path = [collection, key, 'events', event_type, timestamp, ordinal]
|
264
264
|
headers = {}
|
265
|
-
headers['If-Match'] = format_ref(ref) if ref
|
265
|
+
headers['If-Match'] = API::Helpers.format_ref(ref) if ref
|
266
266
|
send_request :delete, path, { query: { purge: true }, headers: headers }
|
267
267
|
end
|
268
268
|
|
269
|
-
#
|
270
|
-
#
|
271
|
-
#
|
272
|
-
#
|
273
|
-
#
|
274
|
-
#
|
275
|
-
#
|
276
|
-
#
|
277
|
-
#
|
278
|
-
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
# - A future version will support ruby Time objects.
|
290
|
-
# +ordinal+:: is optional.
|
291
|
-
#
|
292
|
-
def list_events(collection, key, event_type, parameters={})
|
293
|
-
Orchestrate::Helpers.range_keys!('event', parameters)
|
294
|
-
send_request :get, [collection, key, 'events', event_type], { query: parameters }
|
269
|
+
# [Lists events associated with a key](http://orchestrate.io/docs/api/#events/list23).
|
270
|
+
# Results are time-ordered in reverse-chronological order, and paginated.
|
271
|
+
# @param collection [#to_s] The name of the collection.
|
272
|
+
# @param key [#to_s] The name of the key.
|
273
|
+
# @param event_type [#to_s] The category for the event.
|
274
|
+
# @param options [Hash] The parameters for the query.
|
275
|
+
# @option options [Integer] :limit (10) The number of results to return. Default 100.
|
276
|
+
# @option options [Date, Time, String, Integer] :start The inclusive start of the range.
|
277
|
+
# @option options [Date, Time, String, Integer] :after The exclusive start of the range.
|
278
|
+
# @option options [Date, Time, String, Integer] :before The exclusive end of the range.
|
279
|
+
# @option options [Date, Time, String, Integer] :end The inclusive end of the range.
|
280
|
+
# @return Orchestrate::API::CollectionResponse
|
281
|
+
# @raise Orchestrate::API::NotFound If the provided collection/key doesn't exist.
|
282
|
+
def list_events(collection, key, event_type, options={})
|
283
|
+
(options.keys & [:start, :after, :before, :end]).each do |param|
|
284
|
+
options[param] = API::Helpers.timestamp(options[param])
|
285
|
+
end
|
286
|
+
API::Helpers.range_keys!('event', options)
|
287
|
+
path = [collection, key, 'events', event_type]
|
288
|
+
send_request :get, path, { query: options, response: API::CollectionResponse }
|
295
289
|
end
|
296
290
|
|
297
|
-
#
|
298
|
-
#
|
299
|
-
|
300
|
-
#
|
301
|
-
#
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
#
|
308
|
-
#
|
291
|
+
# @!endgroup
|
292
|
+
# @!group Graphs / Relations
|
293
|
+
|
294
|
+
# [Retrieves a relation's associated objects](http://orchestrate.io/docs/api/#graph/get26).
|
295
|
+
# @param collection [#to_s] The name of the collection.
|
296
|
+
# @param key [#to_s] The name of the key.
|
297
|
+
# @param kinds [#to_s] The relationship kinds and depth to query.
|
298
|
+
# @example Retrieves the friend's of John's family
|
299
|
+
# client.get_relations(:users, 'john', :family, :friends)
|
300
|
+
# @example If the relation facets exist in an array, use:
|
301
|
+
# relations = [:family, :friends]
|
302
|
+
# client.get_relations(:users, 'john', *relations)
|
303
|
+
# @return Orchestrate::API::CollectionResponse
|
304
|
+
# @raise Orchestrate::API::NotFound If the given collection/key doesn't exist.
|
309
305
|
def get_relations(collection, key, *kinds)
|
310
306
|
path = [collection, key, 'relations'].concat(kinds)
|
311
|
-
send_request :get, path
|
307
|
+
send_request :get, path, {response: API::CollectionResponse}
|
312
308
|
end
|
313
309
|
|
314
|
-
#
|
315
|
-
#
|
316
|
-
#
|
317
|
-
#
|
318
|
-
#
|
319
|
-
#
|
320
|
-
#
|
321
|
-
#
|
322
|
-
#
|
323
|
-
# +to_key+:: a String or Symbol representing the key for the related item.
|
324
|
-
#
|
310
|
+
# [Creates a relationship between two Key/Value objects](http://orchestrate.io/docs/api/#graph/put).
|
311
|
+
# Relations can span collections.
|
312
|
+
# @param collection [#to_s] The name of the collection.
|
313
|
+
# @param key [#to_s] The name of the key.
|
314
|
+
# @param kind [#to_s] The kind of relationship to create.
|
315
|
+
# @param to_collection [#to_s] The name of the collection to relate to.
|
316
|
+
# @param to_key [#to_s] The name of the key to relate to.
|
317
|
+
# @return Orchestrate::API::Response
|
318
|
+
# @raise Orchestrate::API::NotFound If either end of the relation doesn't exist.
|
325
319
|
def put_relation(collection, key, kind, to_collection, to_key)
|
326
320
|
send_request :put, [collection, key, 'relation', kind, to_collection, to_key]
|
327
321
|
end
|
328
322
|
|
329
|
-
#
|
330
|
-
#
|
331
|
-
#
|
332
|
-
#
|
333
|
-
#
|
334
|
-
#
|
335
|
-
#
|
336
|
-
# +kind+:: a String or Symbol value representing the relation type.
|
337
|
-
# +to_collection_name+:: a String or Symbol representing the name of the collection the related item belongs.
|
338
|
-
# +to_key+:: a String or Symbol representing the key for the related item.
|
339
|
-
#
|
323
|
+
# [Deletes a relationship between two objects](http://orchestrate.io/docs/api/#graph/delete28).
|
324
|
+
# @param collection [#to_s] The name of the collection.
|
325
|
+
# @param key [#to_s] The name of the key.
|
326
|
+
# @param kind [#to_s] The kind of relationship to delete.
|
327
|
+
# @param to_collection [#to_s] The name of the collection to relate to.
|
328
|
+
# @param to_key [#to_s] The name of the key to relate to.
|
329
|
+
# @return Orchestrate::API::Response
|
340
330
|
def delete_relation(collection, key, kind, to_collection, to_key)
|
341
331
|
path = [collection, key, 'relation', kind, to_collection, to_key]
|
342
332
|
send_request :delete, path, { query: {purge: true} }
|
343
333
|
end
|
344
334
|
|
345
|
-
#
|
346
|
-
|
347
|
-
#
|
348
|
-
#
|
349
|
-
#
|
350
|
-
# output a warning to STDERR.
|
351
|
-
#
|
352
|
-
# Example:
|
335
|
+
# @!endgroup
|
336
|
+
|
337
|
+
# Performs requests in parallel. Requires using a Faraday adapter that supports parallel requests.
|
338
|
+
# @yieldparam accumulator [Hash] A place to store the results of the parallel responses.
|
339
|
+
# @example Performing three requests at once
|
353
340
|
# responses = client.in_parallel do |r|
|
354
341
|
# r[:some_items] = client.list(:site_globals)
|
355
342
|
# r[:user] = client.get(:users, current_user_key)
|
356
343
|
# r[:user_feed] = client.list_events(:users, current_user_key, :notices)
|
357
344
|
# end
|
358
|
-
#
|
345
|
+
# @see README See the Readme for more examples.
|
359
346
|
def in_parallel(&block)
|
360
347
|
accumulator = {}
|
361
348
|
http.in_parallel do
|
@@ -364,47 +351,48 @@ module Orchestrate
|
|
364
351
|
accumulator
|
365
352
|
end
|
366
353
|
|
367
|
-
#
|
368
|
-
#
|
369
|
-
#
|
370
|
-
#
|
371
|
-
#
|
372
|
-
#
|
373
|
-
#
|
374
|
-
#
|
375
|
-
#
|
376
|
-
#
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
body = opts.fetch(:body, '')
|
383
|
-
headers = opts.fetch(:headers, {})
|
354
|
+
# Performs an HTTP request against the Orchestrate API
|
355
|
+
# @param method [Symbol] The HTTP method - :get, :post, :put, :delete
|
356
|
+
# @param path [Array<#to_s>] Path segments for the request's URI. Prepended by 'v0'.
|
357
|
+
# @param options [Hash] extra parameters
|
358
|
+
# @option options [Hash] :query ({}) Query String parameters.
|
359
|
+
# @option options [#to_json] :body ('') The request body.
|
360
|
+
# @option options [Hash] :headers ({}) Extra request headers.
|
361
|
+
# @option options [Class] :response (Orchestrate::API::Response) A subclass of Orchestrate::API::Response to instantiate and return
|
362
|
+
# @return API::Response
|
363
|
+
# @raise [Orchestrate::API::RequestError, Orchestrate::API::ServiceError] see http://orchestrate.io/docs/api/#errors
|
364
|
+
def send_request(method, path, options={})
|
365
|
+
path = ['/v0'].concat(path).join('/')
|
366
|
+
query_string = options.fetch(:query, {})
|
367
|
+
body = options.fetch(:body, '')
|
368
|
+
headers = options.fetch(:headers, {})
|
384
369
|
headers['User-Agent'] = "ruby/orchestrate/#{Orchestrate::VERSION}"
|
385
370
|
headers['Accept'] = 'application/json' if method == :get
|
386
371
|
|
387
|
-
http.send(method) do |request|
|
388
|
-
|
389
|
-
request.url url, query_string
|
372
|
+
response = http.send(method) do |request|
|
373
|
+
request.url path, query_string
|
390
374
|
if [:put, :post].include?(method)
|
391
375
|
headers['Content-Type'] = 'application/json'
|
392
376
|
request.body = body.to_json
|
393
377
|
end
|
394
378
|
headers.each {|header, value| request[header] = value }
|
395
379
|
end
|
396
|
-
end
|
397
|
-
|
398
|
-
# ------------------------------------------------------------------------
|
399
380
|
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
381
|
+
if ! response.success?
|
382
|
+
err_type = API::ERRORS.find do |err|
|
383
|
+
err.status == response.status && err.code == response.body['code']
|
384
|
+
end
|
385
|
+
if err_type
|
386
|
+
raise err_type.new(response)
|
387
|
+
elsif response.status >= 500
|
388
|
+
raise API::ServiceError.new(response)
|
389
|
+
elsif response.status >= 400
|
390
|
+
raise API::RequestError.new(response)
|
391
|
+
end
|
406
392
|
end
|
407
|
-
|
393
|
+
response_class = options.fetch(:response, API::Response)
|
394
|
+
response_class.new(response, self)
|
395
|
+
end
|
408
396
|
end
|
409
397
|
|
410
398
|
end
|