myjohndeere 0.0.1

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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +52 -0
  3. data/Gemfile +16 -0
  4. data/Gemfile.lock +37 -0
  5. data/LICENSE +21 -0
  6. data/README.md +109 -0
  7. data/Rakefile +8 -0
  8. data/lib/myjohndeere.rb +132 -0
  9. data/lib/myjohndeere/access_token.rb +79 -0
  10. data/lib/myjohndeere/api_support_item.rb +27 -0
  11. data/lib/myjohndeere/boundary.rb +18 -0
  12. data/lib/myjohndeere/core_ext/string.rb +9 -0
  13. data/lib/myjohndeere/errors.rb +10 -0
  14. data/lib/myjohndeere/field.rb +28 -0
  15. data/lib/myjohndeere/file_resource.rb +61 -0
  16. data/lib/myjohndeere/hash_utils.rb +33 -0
  17. data/lib/myjohndeere/json_attributes.rb +39 -0
  18. data/lib/myjohndeere/list_object.rb +94 -0
  19. data/lib/myjohndeere/map_layer.rb +41 -0
  20. data/lib/myjohndeere/map_layer_summary.rb +40 -0
  21. data/lib/myjohndeere/map_legend_item.rb +10 -0
  22. data/lib/myjohndeere/metadata_item.rb +8 -0
  23. data/lib/myjohndeere/organization.rb +16 -0
  24. data/lib/myjohndeere/organization_owned_resource.rb +17 -0
  25. data/lib/myjohndeere/requestable.rb +36 -0
  26. data/lib/myjohndeere/response.rb +31 -0
  27. data/lib/myjohndeere/rest_methods.rb +64 -0
  28. data/lib/myjohndeere/single_resource.rb +13 -0
  29. data/lib/myjohndeere/util.rb +54 -0
  30. data/lib/myjohndeere/version.rb +3 -0
  31. data/myjohndeere.gemspec +23 -0
  32. data/spec/fixtures.json +778 -0
  33. data/test/api_fixtures.rb +29 -0
  34. data/test/test_access_token.rb +60 -0
  35. data/test/test_boundary.rb +37 -0
  36. data/test/test_field.rb +47 -0
  37. data/test/test_file_resource.rb +48 -0
  38. data/test/test_helper.rb +36 -0
  39. data/test/test_list_object.rb +74 -0
  40. data/test/test_map_layer.rb +52 -0
  41. data/test/test_map_layer_summary.rb +52 -0
  42. data/test/test_myjohndeere.rb +56 -0
  43. data/test/test_organization.rb +42 -0
  44. data/test/test_requestable.rb +15 -0
  45. data/test/test_rest_methods.rb +34 -0
  46. data/test/test_util.rb +86 -0
  47. metadata +118 -0
@@ -0,0 +1,17 @@
1
+ module MyJohnDeere
2
+ class OrganizationOwnedResource < SingleResource
3
+ attr_accessor :organization_id
4
+
5
+ def initialize(json_object, access_token = nil)
6
+ super(json_object, access_token)
7
+ self.organization_id = extract_link_with_rel_from_list("owningOrganization", /organizations\/([^\/]+)\Z/)
8
+ end
9
+
10
+ def self.owning_organization_link_item(organization_id)
11
+ {
12
+ rel: "owningOrganization",
13
+ uri: "#{MyJohnDeere.configuration.endpoint}/organizations/#{organization_id}"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ module MyJohnDeere
2
+ class Requestable
3
+ attr_accessor :access_token, :links
4
+
5
+ def initialize(json_object = {}, access_token = nil)
6
+ self.links = json_object["links"] || []
7
+ self.access_token = access_token
8
+ approved_class = MyJohnDeere::AccessToken
9
+ if !self.access_token.nil? && !self.access_token.is_a?(approved_class) then
10
+ raise ArgumentError.new("Expected a #{approved_class}, do not know how to handle #{self.access_token.class}")
11
+ end
12
+ end
13
+
14
+ def extract_link_with_rel_from_list(rel_target, regex_to_capture_item)
15
+ link = self.links.detect { |l| l["rel"] == rel_target }
16
+ if link then
17
+ return regex_to_capture_item.match(link["uri"])[1]
18
+ else
19
+ return nil
20
+ end
21
+ end
22
+
23
+ def self.get_created_id_from_response_headers(resource, response)
24
+ # 201 is the expected response code
25
+ # The lowercase location shouldn't be needed but sometimes it is returned as lowercase...
26
+ created_id = response.http_headers["Location"] || response.http_headers["location"]
27
+ if !created_id.nil? then
28
+ created_id = /#{resource}\/([^\/]+)\Z/.match(created_id)[1]
29
+ else
30
+ # didn't succeed
31
+ MyJohnDeere.logger.info("Failed to create a #{resource}: #{response}")
32
+ return nil
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ module MyJohnDeere
2
+ class Response
3
+ attr_accessor :request_id
4
+ attr_accessor :http_body
5
+ attr_accessor :http_headers
6
+ attr_accessor :http_status
7
+ attr_accessor :data
8
+ def initialize(response)
9
+ self.http_headers = {}
10
+ response.each_capitalized_name do |n|
11
+ self.http_headers[n] = response[n]
12
+ end
13
+
14
+ self.http_body = response.body
15
+ if response.body then
16
+ begin
17
+ self.data = JSON.parse(response.body)
18
+ rescue JSON::ParserError
19
+ self.data = nil
20
+ end
21
+ else
22
+ self.data = nil
23
+ end
24
+ self.http_status = response.code.to_i
25
+ end
26
+
27
+ def code
28
+ return http_status
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,64 @@
1
+ module MyJohnDeere
2
+ module RESTMethods
3
+ module ClassMethods
4
+ attr_accessor :base_jd_resource
5
+ attr_accessor :retrieve_resource_path
6
+ attr_accessor :list_resource_path
7
+ # If the resource requires a base resource, specify it in the format of:
8
+ # <resource_singular_name_id>: <ID>
9
+ def list(access_token, options = {})
10
+ validate_access_token(access_token)
11
+ options = {count: 10, start: 0, etag: nil}.merge(options)
12
+ options[:body] ||= {}
13
+ # The count and start are in this list,so move them into the body
14
+ SPECIAL_BODY_PARAMETERS.each do |sbp|
15
+ options[:body][sbp] = options[sbp]
16
+ end
17
+
18
+ response = access_token.execute_request(:get, build_resouce_base_path!(self.list_resource_path, options),
19
+ options
20
+ )
21
+ return ListObject.new(
22
+ self,
23
+ access_token,
24
+ response.data,
25
+ options: options.merge(
26
+ etag: response.http_headers[MyJohnDeere::ETAG_HEADER_KEY]
27
+ )
28
+ )
29
+ end
30
+
31
+ def retrieve(access_token, id, options={})
32
+ validate_access_token(access_token)
33
+ response = access_token.execute_request(:get,
34
+ "#{build_resouce_base_path!(self.retrieve_resource_path, options)}/#{id}",
35
+ options)
36
+
37
+ return new(response.data, access_token)
38
+ end
39
+
40
+ def build_resouce_base_path!(resource_path, options)
41
+ base_resources = {}
42
+ options.each do |key, val|
43
+ base_resources[key] = options.delete(key) if key.match(/_id\Z/)
44
+ end
45
+ return resource_path if base_resources.nil? || base_resources.empty?
46
+ MyJohnDeere.logger.info("Building resource path: #{resource_path}, with ids: #{base_resources}")
47
+ return resource_path % base_resources
48
+ end
49
+
50
+ def validate_access_token(access_token)
51
+ raise ArgumentError.new("The first argument must be an #{AccessToken}") if !access_token.is_a?(AccessToken)
52
+ end
53
+ end
54
+
55
+ module InstanceMethods
56
+
57
+ end
58
+
59
+ def self.included(receiver)
60
+ receiver.extend ClassMethods
61
+ receiver.send :include, InstanceMethods
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,13 @@
1
+ module MyJohnDeere
2
+ class SingleResource < Requestable
3
+ include RESTMethods
4
+ include JSONAttributes
5
+ attr_accessor :deleted
6
+
7
+ def initialize(json_object, access_token = nil)
8
+ super(json_object, access_token)
9
+ setup_attributes(json_object)
10
+ self.deleted = self.links.any? { |link_hash| link_hash["rel"] == "delete" }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,54 @@
1
+ module MyJohnDeere
2
+ class Util
3
+ def self.build_path_headers_and_body(method, path, headers: {}, body: "", etag: nil)
4
+ # in the case of following one of their paths, just clear out the base
5
+ path = path.sub(MyJohnDeere.configuration.endpoint, '')
6
+ path = "/#{path}" if not path.start_with?("/")
7
+ # always trim platform from the beginning as we have that in our base
8
+ path = path.sub(/\A\/?platform/, "")
9
+
10
+ default_headers = nil
11
+ if method == :post || method == :put then
12
+ body = body.to_json() if body.is_a?(Hash)
13
+ default_headers = MyJohnDeere::DEFAULT_POST_HEADER.dup
14
+ content_length = body.length
15
+ default_headers["Content-Length"] ||= body.length.to_s if content_length > 0
16
+ else
17
+ default_headers = MyJohnDeere::DEFAULT_REQUEST_HEADER
18
+ end
19
+ headers = default_headers.merge(headers || {})
20
+
21
+ if REQUEST_METHODS_TO_PUT_PARAMS_IN_URL.include?(method) then
22
+ if !etag.nil? then
23
+ # Pass an empty string to have it start
24
+ headers[MyJohnDeere::ETAG_HEADER_KEY] = etag
25
+ end
26
+
27
+ # we'll only accept hashes for the body for now
28
+ if body.is_a?(Hash) then
29
+ uri = URI.parse(path)
30
+ new_query_ar = URI.decode_www_form(uri.query || '')
31
+
32
+ # For reasons beyond me, these are specified as non-parameters
33
+ special_parameters = {}
34
+ SPECIAL_BODY_PARAMETERS.each do |sbp|
35
+ special_parameters[sbp] = body.delete(sbp)
36
+ end
37
+
38
+ body.each do |key, val|
39
+ new_query_ar << [key.to_s, val.to_s]
40
+ end
41
+ special_parameters.each do |key,val|
42
+ next if val.nil?
43
+ query_string = "#{key}=#{val}"
44
+ uri.path = "#{uri.path};#{query_string}" if !uri.path.include?(query_string)
45
+ end
46
+ uri.query = URI.encode_www_form(new_query_ar)
47
+ path = uri.to_s
48
+ end
49
+ end
50
+
51
+ return path, headers, body
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ module MyJohnDeere
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,23 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require 'myjohndeere/version'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = 'myjohndeere'
7
+ s.version = MyJohnDeere::VERSION
8
+ s.required_ruby_version = '>= 1.9.3'
9
+ s.summary = 'Ruby bindings for the MyJohnDeere API'
10
+ s.description = ' MyJohnDeere is used to make data-driven decisions to maximize your return on every acre. This Ruby Gem is provided as a convenient way to access their API.'
11
+ s.author = 'Paul Susmarski'
12
+ s.email = 'paul@susmarski.com'
13
+ s.homepage = 'http://rubygems.org/gems/myjohndeere'
14
+ s.license = 'MIT'
15
+
16
+ s.add_dependency "oauth", ">= 0.5.3"
17
+
18
+ s.files = Dir['lib/**/*.rb']
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- test/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ['lib']
23
+ end
@@ -0,0 +1,778 @@
1
+ {
2
+ "file_resource" : {
3
+ "links": [
4
+ {
5
+ "rel": "self",
6
+ "uri": "https://sandboxapi.deere.com/platform/fileResources/8sz21113-2afj-9302-837j-92jlsk92jd095kd"
7
+ },
8
+ {
9
+ "rel": "owningOrganization",
10
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
11
+ },
12
+ {
13
+ "rel": "targetResource",
14
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd"
15
+ }
16
+ ],
17
+ "id": "8sz21113-2afj-9302-837j-92jlsk92jd095kd",
18
+ "mimeType": "image/png",
19
+ "metadata": [
20
+ {
21
+ "name": "The Name",
22
+ "value": "The Value"
23
+ }
24
+ ],
25
+ "timestamp": "2016-01-02T16:14:23.421Z"
26
+ },
27
+ "file_resources" : {
28
+ "links": [
29
+ {
30
+ "rel": "self",
31
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd/fileResources"
32
+ },
33
+ {
34
+ "rel": "nextPage",
35
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd/fileResources;start=10;count=10"
36
+ }
37
+ ],
38
+ "total": 1,
39
+ "values": [
40
+ {
41
+ "links": [
42
+ {
43
+ "rel": "self",
44
+ "uri": "https://sandboxapi.deere.com/platform/notes/NOTE_GUID"
45
+ },
46
+ {
47
+ "rel": "owningOrganization",
48
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
49
+ },
50
+ {
51
+ "rel": "targetResource",
52
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd"
53
+ }
54
+ ],
55
+ "id": "8sz21113-2afj-9302-837j-92jlsk92jd095kd",
56
+ "fileName": "fileName.png",
57
+ "mimeType": "image/png",
58
+ "metadata": [
59
+ {
60
+ "name": "The Name",
61
+ "value": "The Value"
62
+ }
63
+ ],
64
+ "timestamp": "2016-01-02T16:14:23.421Z"
65
+ }
66
+ ]
67
+ },
68
+ "map_layer" : {
69
+ "links": [
70
+ {
71
+ "rel": "self",
72
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd"
73
+ },
74
+ {
75
+ "rel": "owningOrganization",
76
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
77
+ },
78
+ {
79
+ "rel": "mapLayerSummary",
80
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummaries/2516aa2c-2c0d-4dae-ba63-5c44ff172a01"
81
+ },
82
+ {
83
+ "rel": "fileResources",
84
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd/fileResources"
85
+ }
86
+ ],
87
+ "id": "83ks9gh3-29fj-9302-837j-92jlsk92jd095kd",
88
+ "title": "The title on the map layer",
89
+ "extent": {
90
+ "minimumLatitude": 41.76073,
91
+ "maximumLatitude": 41.771366,
92
+ "minimumLongitude": -93.488106,
93
+ "maximumLongitude": -93.4837
94
+ },
95
+ "legends": {
96
+ "unitId": "seeds1ha-1",
97
+ "ranges": [
98
+ {
99
+ "label": "Some Label",
100
+ "minimum": 87300,
101
+ "maximum": 87300,
102
+ "hexColor": "#0BA74A",
103
+ "percent": 0.13
104
+ }
105
+ ]
106
+ }
107
+ },
108
+ "map_layers" : {
109
+ "links": [
110
+ {
111
+ "rel": "self",
112
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummary/2516aa2c-1c0d-4dae-ba63-5c44ff172a01/mapLayers"
113
+ },
114
+ {
115
+ "rel": "nextPage",
116
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummary/2516aa2c-1c0d-4dae-ba63-5c44ff172a01/mapLayers;start=10;count=10"
117
+ }
118
+ ],
119
+ "total": 1,
120
+ "values": [
121
+ {
122
+ "links": [
123
+ {
124
+ "rel": "self",
125
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd"
126
+ },
127
+ {
128
+ "rel": "owningOrganization",
129
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
130
+ },
131
+ {
132
+ "rel": "mapLayerSummary",
133
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummaries/2516aa2c-1c0d-4dae-ba63-5c44ff172a01"
134
+ },
135
+ {
136
+ "rel": "fileResources",
137
+ "uri": "https://sandboxapi.deere.com/platform/mapLayers/83ks9gh3-29fj-9302-837j-92jlsk92jd095kd/fileResources"
138
+ }
139
+ ],
140
+ "id": "83ks9gh3-29fj-9302-837j-92jlsk92jd095kd",
141
+ "title": "The title on the map layer",
142
+ "extent": {
143
+ "minimumLatitude": 41.76073,
144
+ "maximumLatitude": 41.771366,
145
+ "minimumLongitude": -93.488106,
146
+ "maximumLongitude": -93.4837
147
+ },
148
+ "legends": {
149
+ "unitId": "seeds1ha-1",
150
+ "ranges": [
151
+ {
152
+ "label": "Some Label",
153
+ "minimum": 87300,
154
+ "maximum": 87300,
155
+ "hexColor": "#0BA74A",
156
+ "percent": 0.13
157
+ }
158
+ ]
159
+ }
160
+ }
161
+ ]
162
+ },
163
+ "map_layer_summary" : {
164
+ "links": [
165
+ {
166
+ "rel": "self",
167
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummaries/2516aa2c-2c0d-4dae-ba63-5c44ff172a01"
168
+ },
169
+ {
170
+ "rel": "owningOrganization",
171
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
172
+ },
173
+ {
174
+ "rel": "contributionDefinition",
175
+ "uri": "https://sandboxapi.deere.com/platform/contributionDefinitions/DEFINITION_GUID"
176
+ },
177
+ {
178
+ "rel": "targetResource",
179
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01"
180
+ },
181
+ {
182
+ "rel": "mapLayers",
183
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummaries/2516aa2c-2c0d-4dae-ba63-5c44ff172a01/mapLayers"
184
+ }
185
+ ],
186
+ "id": "2516aa2c-1c0d-4dae-ba63-5c44ff172a01",
187
+ "title": "some title",
188
+ "text": "description of the map layers",
189
+ "metadata": [
190
+ {
191
+ "name": "The Name",
192
+ "value": "The Value"
193
+ }
194
+ ],
195
+ "dateCreated": "2016-01-02T16:14:23.421Z",
196
+ "lastModifiedDate": "2016-01-02T16:14:23.421Z"
197
+ },
198
+ "map_layer_summaries" : {
199
+ "links": [
200
+ {
201
+ "rel": "self",
202
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/mapLayerSummaries"
203
+ },
204
+ {
205
+ "rel": "nextPage",
206
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/mapLayerSummaries;start=10;count=10"
207
+ }
208
+ ],
209
+ "total": 1,
210
+ "values": [
211
+ {
212
+ "links": [
213
+ {
214
+ "rel": "self",
215
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummaries/2516aa2c-2c0d-4dae-ba63-5c44ff172a01"
216
+ },
217
+ {
218
+ "rel": "owningOrganization",
219
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
220
+ },
221
+ {
222
+ "rel": "contributionDefinition",
223
+ "uri": "https://sandboxapi.deere.com/platform/contributionDefinitions/DEFINITION_GUID"
224
+ },
225
+ {
226
+ "rel": "targetResource",
227
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01"
228
+ },
229
+ {
230
+ "rel": "mapLayers",
231
+ "uri": "https://sandboxapi.deere.com/platform/mapLayerSummaries/2516aa2c-2c0d-4dae-ba63-5c44ff172a01/mapLayers"
232
+ }
233
+ ],
234
+ "id": "2516aa2c-1c0d-4dae-ba63-5c44ff172a01",
235
+ "title": "some title",
236
+ "text": "description of the map layers",
237
+ "metadata": [
238
+ {
239
+ "name": "The Name",
240
+ "value": "The Value"
241
+ }
242
+ ],
243
+ "dateCreated": "2016-01-02T16:14:23.421Z",
244
+ "lastModifiedDate": "2016-01-02T16:14:23.421Z"
245
+ }
246
+ ]
247
+ },
248
+ "api_catalog" : {
249
+ "@type":"ApiCatalog",
250
+ "links":[
251
+ {
252
+ "@type":"Link",
253
+ "rel":"oauthRequestToken",
254
+ "uri":"https://api.soa-proxy.deere.com/platform/oauth/request_token"
255
+ },
256
+ {
257
+ "@type":"Link",
258
+ "rel":"oauthAuthorizeRequestToken",
259
+ "uri":"https://my.deere.com/consentToUseOfData?oauth_token={token}"
260
+ },
261
+ {
262
+ "@type":"Link",
263
+ "rel":"oauthAccessToken",
264
+ "uri":"https://api.soa-proxy.deere.com/platform/oauth/access_token"
265
+ },
266
+ {
267
+ "@type":"Link",
268
+ "rel":"files",
269
+ "uri":"https://api.soa-proxy.deere.com/platform/files"
270
+ },
271
+ {
272
+ "@type":"Link",
273
+ "rel":"fileTransfers",
274
+ "uri":"https://api.soa-proxy.deere.com/platform/fileTransfers"
275
+ },
276
+ {
277
+ "@type":"Link",
278
+ "rel":"currentUser",
279
+ "uri":"https://api.soa-proxy.deere.com/platform/users/@currentUser"
280
+ },
281
+ {
282
+ "@type":"Link",
283
+ "rel":"organizations",
284
+ "uri":"https://api.soa-proxy.deere.com/platform/organizations"
285
+ },
286
+ {
287
+ "@type":"Link",
288
+ "rel":"alertIgnorePreferences",
289
+ "uri":"https://api.soa-proxy.deere.com/platform/alertIgnorePreferences"
290
+ },
291
+ {
292
+ "@type":"Link",
293
+ "rel":"partnerships",
294
+ "uri":"https://api.soa-proxy.deere.com/platform/partnerships"
295
+ },
296
+ {
297
+ "@type":"Link",
298
+ "rel":"machineUtilization",
299
+ "uri":"https://api.soa-proxy.deere.com/platform/machineUtilization"
300
+ },
301
+ {
302
+ "@type":"Link",
303
+ "rel":"aggregatedMachineUtilization",
304
+ "uri":"https://api.soa-proxy.deere.com/platform/aggregatedMachineUtilization"
305
+ },
306
+ {
307
+ "@type":"Link",
308
+ "rel":"geofences",
309
+ "uri":"https://api.soa-proxy.deere.com/platform/geofences"
310
+ },
311
+ {
312
+ "@type":"Link",
313
+ "rel":"currentToken",
314
+ "uri":"https://api.soa-proxy.deere.com/platform/oauthTokens/@currentToken"
315
+ },
316
+ {
317
+ "@type":"Link",
318
+ "rel":"notificationEvents",
319
+ "uri":"https://api.soa-proxy.deere.com/platform/notificationEvents"
320
+ }
321
+ ]
322
+ },
323
+ "field_with_embedded_boundary" : {
324
+ "@type":"Field",
325
+ "name":"AndersonFarms",
326
+ "boundaries":[
327
+ {
328
+ "@type":"Boundary",
329
+ "name":"a",
330
+ "modifiedTime":"2017-08-04T21:45:51.469Z",
331
+ "area":{
332
+ "@type":"MeasurementAsDouble",
333
+ "valueAsDouble":15.892707870809991,
334
+ "unit":"ha"
335
+ },
336
+ "multipolygons":[
337
+ {
338
+ "@type":"Polygon",
339
+ "rings":[
340
+ {
341
+ "@type":"Ring",
342
+ "points":[
343
+ {
344
+ "@type":"Point",
345
+ "lat":40.095079098,
346
+ "lon":-105.032172203
347
+ },
348
+ {
349
+ "@type":"Point",
350
+ "lat":40.095111927,
351
+ "lon":-105.023052692
352
+ },
353
+ {
354
+ "@type":"Point",
355
+ "lat":40.096425084,
356
+ "lon":-105.023825169
357
+ },
358
+ {
359
+ "@type":"Point",
360
+ "lat":40.096802611,
361
+ "lon":-105.024554729
362
+ },
363
+ {
364
+ "@type":"Point",
365
+ "lat":40.096457912,
366
+ "lon":-105.025134087
367
+ },
368
+ {
369
+ "@type":"Point",
370
+ "lat":40.097245793,
371
+ "lon":-105.029489994
372
+ },
373
+ {
374
+ "@type":"Point",
375
+ "lat":40.097492004,
376
+ "lon":-105.030562878
377
+ },
378
+ {
379
+ "@type":"Point",
380
+ "lat":40.097787456,
381
+ "lon":-105.031678677
382
+ },
383
+ {
384
+ "@type":"Point",
385
+ "lat":40.097771042,
386
+ "lon":-105.032193661
387
+ },
388
+ {
389
+ "@type":"Point",
390
+ "lat":40.095079098,
391
+ "lon":-105.032172203
392
+ }
393
+ ],
394
+ "type":"exterior",
395
+ "passable":true
396
+ }
397
+ ]
398
+ }
399
+ ],
400
+ "extent":{
401
+ "@type":"Extent",
402
+ "topLeft":{
403
+ "@type":"Point",
404
+ "lat":40.097787456,
405
+ "lon":-105.032193661
406
+ },
407
+ "bottomRight":{
408
+ "@type":"Point",
409
+ "lat":40.095079098,
410
+ "lon":-105.023052692
411
+ }
412
+ },
413
+ "id":"f4828b25-2a92-12a4-bf3e-a107c39ecb84",
414
+ "links":[
415
+ {
416
+ "@type":"Link",
417
+ "rel":"self",
418
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/boundaries/f4828b25-2a92-4f2d-bf3e-a107c39ecb84"
419
+ },
420
+ {
421
+ "@type":"Link",
422
+ "rel":"owningOrganization",
423
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234"
424
+ }
425
+ ],
426
+ "active":true
427
+ }
428
+ ],
429
+ "id":"2516aa2c-2c0d-4dae-ba63-5c64fd172d01",
430
+ "links":[
431
+ {
432
+ "@type":"Link",
433
+ "rel":"self",
434
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01"
435
+ },
436
+ {
437
+ "@type":"Link",
438
+ "rel":"clients",
439
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/clients"
440
+ },
441
+ {
442
+ "@type":"Link",
443
+ "rel":"notes",
444
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/notes"
445
+ },
446
+ {
447
+ "@type":"Link",
448
+ "rel":"farms",
449
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/farms"
450
+ },
451
+ {
452
+ "@type":"Link",
453
+ "rel":"owningOrganization",
454
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234"
455
+ },
456
+ {
457
+ "@type":"Link",
458
+ "rel":"simplifiedBoundaries",
459
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/boundaries?simple=true"
460
+ },
461
+ {
462
+ "@type":"Link",
463
+ "rel":"addBoundary",
464
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/boundaries"
465
+ },
466
+ {
467
+ "@type":"Link",
468
+ "rel":"activeBoundary",
469
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/boundaries/f4828b25-2a92-4f2d-bf3e-a107c39ecb84"
470
+ },
471
+ {
472
+ "@type":"Link",
473
+ "rel":"fieldOperation",
474
+ "uri":"https://sandboxapi.deere.com/platform/organizations/1234/fields/2516aa2c-2c0d-4dae-ba63-5c64fd172d01/fieldOperations"
475
+ }
476
+ ]
477
+ },
478
+ "boundary" : {
479
+ "name": "2/25/2015 6:01:19 PM",
480
+ "area": {
481
+ "valueAsDouble": 70.8407,
482
+ "unit": "ha"
483
+ },
484
+ "multipolygons": [
485
+ {
486
+ "rings": [
487
+ {
488
+ "points": [
489
+ {
490
+ "lat": 41.538383,
491
+ "lon": -90.81443
492
+ },
493
+ {
494
+ "lat": 41.530777,
495
+ "lon": -90.81459
496
+ },
497
+ {
498
+ "lat": 41.530895,
499
+ "lon": -90.82465
500
+ },
501
+ {
502
+ "lat": 41.538517,
503
+ "lon": -90.82444
504
+ },
505
+ {
506
+ "lat": 41.538383,
507
+ "lon": -90.81443
508
+ }
509
+ ],
510
+ "type": "exterior",
511
+ "passable": true
512
+ }
513
+ ]
514
+ }
515
+ ],
516
+ "extent": {
517
+ "topLeft": {
518
+ "lat": 41.538517,
519
+ "lon": -90.82465
520
+ },
521
+ "bottomRight": {
522
+ "lat": 41.530777,
523
+ "lon": -90.81443
524
+ }
525
+ },
526
+ "links": [
527
+ {
528
+ "rel": "self",
529
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/boundaries/6232611a-0303-0234-8g7d-e1e1e11871b8"
530
+ },
531
+ // TODO: CONTACT JOHN DEERE TESTING DOES NOT SHOW THIS IS IN EXISTANCE
532
+ // {
533
+ // "rel": "fields",
534
+ // "uri": "https://sandboxapi.deere.com/platform/organizations/1234/boundaries/6232611a-0303-0234-8g7d-e1e1e11871b8/fields"
535
+ // },
536
+ {
537
+ "rel": "owningOrganization",
538
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
539
+ }
540
+ ],
541
+ "id": "6232611a-0303-0234-8g7d-e1e1e11871b8",
542
+ "active": "true"
543
+ },
544
+ "boundaries" : {
545
+ "links": [
546
+ {
547
+ "rel": "self",
548
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/6232611a-0303-0234-8g7d-e1e1e11871b8/boundaries"
549
+ }
550
+ ],
551
+ "total": 1,
552
+ "values": [
553
+ {
554
+ "name": "2/25/2015 6:01:19 PM",
555
+ "area": {
556
+ "valueAsDouble": 70.8407,
557
+ "unit": "ha"
558
+ },
559
+ "multipolygons": [
560
+ {
561
+ "rings": [
562
+ {
563
+ "points": [
564
+ {
565
+ "lat": 41.538383,
566
+ "lon": -90.81443
567
+ },
568
+ {
569
+ "lat": 41.530777,
570
+ "lon": -90.81459
571
+ },
572
+ {
573
+ "lat": 41.530895,
574
+ "lon": -90.82465
575
+ },
576
+ {
577
+ "lat": 41.538517,
578
+ "lon": -90.82444
579
+ },
580
+ {
581
+ "lat": 41.538383,
582
+ "lon": -90.81443
583
+ }
584
+ ],
585
+ "type": "exterior",
586
+ "passable": true
587
+ }
588
+ ]
589
+ }
590
+ ],
591
+ "extent": {
592
+ "topLeft": {
593
+ "lat": 41.538517,
594
+ "lon": -90.82465
595
+ },
596
+ "bottomRight": {
597
+ "lat": 41.530777,
598
+ "lon": -90.81443
599
+ }
600
+ },
601
+ "links": [
602
+ {
603
+ "rel": "self",
604
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/boundaries/6232611a-0303-0234-8g7d-e1e1e11871b8"
605
+ },
606
+ // TODO: CONTACT JOHN DEERE TESTING DOES NOT SHOW THIS IS IN EXISTANCE
607
+ // {
608
+ // "rel": "fields",
609
+ // "uri": "https://sandboxapi.deere.com/platform/organizations/1234/boundaries/6232611a-0303-0234-8g7d-e1e1e11871b8/fields"
610
+ // },
611
+ {
612
+ "rel": "owningOrganization",
613
+ "uri": "https://api.deere.com/platform/organizations/1234"
614
+ }
615
+ ],
616
+ "id": "6232611a-0303-0234-8g7d-e1e1e11871b8",
617
+ "active": "true"
618
+ }
619
+ ]
620
+ },
621
+ "field" : {
622
+ "name": "Nautilus",
623
+ "links": [
624
+ {
625
+ "rel": "self",
626
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg"
627
+ },
628
+ {
629
+ "rel": "boundaries",
630
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg/boundaries"
631
+ },
632
+ {
633
+ "rel": "clients",
634
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg/clients"
635
+ },
636
+ {
637
+ "rel": "farms",
638
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg/farms"
639
+ },
640
+ {
641
+ "rel": "owningOrganization",
642
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
643
+ },
644
+ {
645
+ "rel": "activeBoundary",
646
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/boundaries/MjEwMV9kN2E2Njg1OC03N"
647
+ }
648
+ ],
649
+ "id": "MWUxZTExODZiMzg"
650
+ },
651
+ "fields" : {
652
+ "links": [
653
+ {
654
+ "rel": "self",
655
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields"
656
+ }
657
+ ],
658
+ "total": 1,
659
+ "values": [
660
+ {
661
+ "name": "Nautilus",
662
+ "links": [
663
+ {
664
+ "rel": "self",
665
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg"
666
+ },
667
+ {
668
+ "rel": "boundaries",
669
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg/boundaries"
670
+ },
671
+ {
672
+ "rel": "clients",
673
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg/clients"
674
+ },
675
+ {
676
+ "rel": "farms",
677
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/fields/MWUxZTExODZiMzg/farms"
678
+ },
679
+ {
680
+ "rel": "owningOrganization",
681
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
682
+ },
683
+ {
684
+ "rel": "activeBoundary",
685
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/boundaries/2Njg1OC03N"
686
+ }
687
+ ],
688
+ "id": "MWUxZTExODZiMzg"
689
+ }
690
+ ]
691
+ },
692
+ "organizations" : {
693
+ "links": [
694
+ {
695
+ "rel": "self",
696
+ "uri": "https://sandboxapi.deere.com/platform/organizations"
697
+ },
698
+ {
699
+ "rel": "nextPage",
700
+ "uri": "https://sandboxapi.deere.com/platform/organizations;start=10;count=10"
701
+ }
702
+ ],
703
+ "total": 27,
704
+ "values": [ {
705
+ "links": [
706
+ {
707
+ "rel": "self",
708
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
709
+ },
710
+ {
711
+ "rel": "machines",
712
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/machines"
713
+ },
714
+ {
715
+ "rel": "wdtCapableMachines",
716
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/machines?capability=wdt"
717
+ },
718
+ {
719
+ "rel": "addresses",
720
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/addresses"
721
+ }
722
+ ],
723
+ "id": "1234",
724
+ "name": "Smith Farms",
725
+ "type": "customer",
726
+ "addresses": [],
727
+ "partnerships": [],
728
+ "member": true
729
+ }
730
+ ]
731
+ },
732
+ "deleted_organization" : {
733
+ "links": [
734
+ {
735
+ "rel": "self",
736
+ "uri": " https://sandboxapi.deere.com/platform/organizations/234578"
737
+ }
738
+ ],
739
+ "total": 1,
740
+ "values": [
741
+ {
742
+ "links": [
743
+ {
744
+ "rel": "delete",
745
+ "uri": " https://sandboxapi.deere.com/platform/organizations/234578"
746
+ }
747
+ ],
748
+ "id": "20201112"
749
+ }
750
+ ]
751
+ },
752
+ "organization" : {
753
+ "links": [
754
+ {
755
+ "rel": "self",
756
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234"
757
+ },
758
+ {
759
+ "rel": "machines",
760
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/machines"
761
+ },
762
+ {
763
+ "rel": "wdtCapableMachines",
764
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/machines?capability=wdt"
765
+ },
766
+ {
767
+ "rel": "addresses",
768
+ "uri": "https://sandboxapi.deere.com/platform/organizations/1234/addresses"
769
+ }
770
+ ],
771
+ "id": "1234",
772
+ "name": "Smith Farms",
773
+ "type": "customer",
774
+ "addresses": [],
775
+ "partnerships": [],
776
+ "member": true
777
+ }
778
+ }