restfully 0.6.3 → 0.7.0.pre

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 (73) hide show
  1. data/README.md +166 -0
  2. data/Rakefile +35 -35
  3. data/bin/restfully +68 -10
  4. data/lib/restfully.rb +8 -14
  5. data/lib/restfully/collection.rb +70 -90
  6. data/lib/restfully/error.rb +2 -0
  7. data/lib/restfully/http.rb +3 -3
  8. data/lib/restfully/http/error.rb +1 -20
  9. data/lib/restfully/http/helper.rb +49 -0
  10. data/lib/restfully/http/request.rb +60 -24
  11. data/lib/restfully/http/response.rb +55 -24
  12. data/lib/restfully/link.rb +32 -24
  13. data/lib/restfully/media_type.rb +70 -0
  14. data/lib/restfully/media_type/abstract_media_type.rb +162 -0
  15. data/lib/restfully/media_type/application_json.rb +21 -0
  16. data/lib/restfully/media_type/application_vnd_bonfire_xml.rb +177 -0
  17. data/lib/restfully/media_type/application_x_www_form_urlencoded.rb +33 -0
  18. data/lib/restfully/media_type/grid5000.rb +67 -0
  19. data/lib/restfully/media_type/wildcard.rb +27 -0
  20. data/lib/restfully/rack.rb +1 -0
  21. data/lib/restfully/rack/basic_auth.rb +26 -0
  22. data/lib/restfully/resource.rb +134 -197
  23. data/lib/restfully/session.rb +127 -70
  24. data/lib/restfully/version.rb +3 -0
  25. data/spec/fixtures/bonfire-collection-with-fragments.xml +6 -0
  26. data/spec/fixtures/bonfire-compute-existing.xml +43 -0
  27. data/spec/fixtures/bonfire-empty-collection.xml +4 -0
  28. data/spec/fixtures/bonfire-experiment-collection.xml +51 -0
  29. data/spec/fixtures/bonfire-network-collection.xml +35 -0
  30. data/spec/fixtures/bonfire-network-existing.xml +6 -0
  31. data/spec/fixtures/bonfire-root.xml +5 -0
  32. data/spec/fixtures/grid5000-rennes-jobs.json +988 -146
  33. data/spec/fixtures/grid5000-rennes.json +63 -0
  34. data/spec/restfully/collection_spec.rb +87 -0
  35. data/spec/restfully/http/helper_spec.rb +18 -0
  36. data/spec/restfully/http/request_spec.rb +97 -0
  37. data/spec/restfully/http/response_spec.rb +53 -0
  38. data/spec/restfully/link_spec.rb +80 -0
  39. data/spec/restfully/media_type/application_vnd_bonfire_xml_spec.rb +153 -0
  40. data/spec/restfully/media_type_spec.rb +117 -0
  41. data/spec/restfully/resource_spec.rb +109 -0
  42. data/spec/restfully/session_spec.rb +229 -0
  43. data/spec/spec_helper.rb +10 -9
  44. metadata +162 -83
  45. data/.document +0 -5
  46. data/CHANGELOG +0 -62
  47. data/README.rdoc +0 -146
  48. data/TODO.rdoc +0 -3
  49. data/VERSION +0 -1
  50. data/examples/grid5000.rb +0 -33
  51. data/examples/scratch.rb +0 -37
  52. data/lib/restfully/extensions.rb +0 -34
  53. data/lib/restfully/http/adapters/abstract_adapter.rb +0 -29
  54. data/lib/restfully/http/adapters/patron_adapter.rb +0 -16
  55. data/lib/restfully/http/adapters/rest_client_adapter.rb +0 -75
  56. data/lib/restfully/http/headers.rb +0 -20
  57. data/lib/restfully/parsing.rb +0 -66
  58. data/lib/restfully/special_array.rb +0 -5
  59. data/lib/restfully/special_hash.rb +0 -5
  60. data/restfully.gemspec +0 -114
  61. data/spec/collection_spec.rb +0 -120
  62. data/spec/fixtures/configuration_file.yml +0 -4
  63. data/spec/fixtures/grid5000-sites.json +0 -540
  64. data/spec/http/error_spec.rb +0 -18
  65. data/spec/http/headers_spec.rb +0 -17
  66. data/spec/http/request_spec.rb +0 -49
  67. data/spec/http/response_spec.rb +0 -19
  68. data/spec/http/rest_client_adapter_spec.rb +0 -35
  69. data/spec/link_spec.rb +0 -61
  70. data/spec/parsing_spec.rb +0 -40
  71. data/spec/resource_spec.rb +0 -320
  72. data/spec/restfully_spec.rb +0 -16
  73. data/spec/session_spec.rb +0 -171
@@ -1,5 +0,0 @@
1
- module Restfully
2
- # To be used to provide facilities such as hash-like lookups
3
- class SpecialArray < Array
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- module Restfully
2
- # To be used later
3
- class SpecialHash < Hash
4
- end
5
- end
data/restfully.gemspec DELETED
@@ -1,114 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{restfully}
8
- s.version = "0.6.3"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Cyril Rohr"]
12
- s.date = %q{2011-04-14}
13
- s.default_executable = %q{restfully}
14
- s.description = %q{Experimental code for auto-generation of wrappers on top of RESTful APIs that follow HATEOAS principles and provide OPTIONS methods and/or Allow headers.}
15
- s.email = %q{cyril.rohr@gmail.com}
16
- s.executables = ["restfully"]
17
- s.extra_rdoc_files = [
18
- "LICENSE",
19
- "README.rdoc"
20
- ]
21
- s.files = [
22
- ".document",
23
- "CHANGELOG",
24
- "LICENSE",
25
- "README.rdoc",
26
- "Rakefile",
27
- "TODO.rdoc",
28
- "VERSION",
29
- "bin/restfully",
30
- "examples/grid5000.rb",
31
- "lib/restfully.rb",
32
- "lib/restfully/collection.rb",
33
- "lib/restfully/error.rb",
34
- "lib/restfully/extensions.rb",
35
- "lib/restfully/http.rb",
36
- "lib/restfully/http/adapters/abstract_adapter.rb",
37
- "lib/restfully/http/adapters/patron_adapter.rb",
38
- "lib/restfully/http/adapters/rest_client_adapter.rb",
39
- "lib/restfully/http/error.rb",
40
- "lib/restfully/http/headers.rb",
41
- "lib/restfully/http/request.rb",
42
- "lib/restfully/http/response.rb",
43
- "lib/restfully/link.rb",
44
- "lib/restfully/parsing.rb",
45
- "lib/restfully/resource.rb",
46
- "lib/restfully/session.rb",
47
- "lib/restfully/special_array.rb",
48
- "lib/restfully/special_hash.rb",
49
- "restfully.gemspec",
50
- "spec/collection_spec.rb",
51
- "spec/fixtures/configuration_file.yml",
52
- "spec/fixtures/grid5000-rennes-jobs.json",
53
- "spec/fixtures/grid5000-sites.json",
54
- "spec/http/error_spec.rb",
55
- "spec/http/headers_spec.rb",
56
- "spec/http/request_spec.rb",
57
- "spec/http/response_spec.rb",
58
- "spec/http/rest_client_adapter_spec.rb",
59
- "spec/link_spec.rb",
60
- "spec/parsing_spec.rb",
61
- "spec/resource_spec.rb",
62
- "spec/restfully_spec.rb",
63
- "spec/session_spec.rb",
64
- "spec/spec_helper.rb"
65
- ]
66
- s.homepage = %q{http://github.com/crohr/restfully}
67
- s.require_paths = ["lib"]
68
- s.rubygems_version = %q{1.5.2}
69
- s.summary = %q{Experimental code for auto-generation of wrappers on top of RESTful APIs that follow some specific conventions.}
70
- s.test_files = [
71
- "examples/grid5000.rb",
72
- "examples/scratch.rb",
73
- "spec/collection_spec.rb",
74
- "spec/http/error_spec.rb",
75
- "spec/http/headers_spec.rb",
76
- "spec/http/request_spec.rb",
77
- "spec/http/response_spec.rb",
78
- "spec/http/rest_client_adapter_spec.rb",
79
- "spec/link_spec.rb",
80
- "spec/parsing_spec.rb",
81
- "spec/resource_spec.rb",
82
- "spec/restfully_spec.rb",
83
- "spec/session_spec.rb",
84
- "spec/spec_helper.rb"
85
- ]
86
-
87
- if s.respond_to? :specification_version then
88
- s.specification_version = 3
89
-
90
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
91
- s.add_runtime_dependency(%q<rest-client>, [">= 1.4"])
92
- s.add_runtime_dependency(%q<json>, [">= 1.2.0"])
93
- s.add_runtime_dependency(%q<backports>, [">= 0"])
94
- s.add_development_dependency(%q<webmock>, [">= 0"])
95
- s.add_development_dependency(%q<rspec>, [">= 0"])
96
- s.add_development_dependency(%q<json>, [">= 0"])
97
- else
98
- s.add_dependency(%q<rest-client>, [">= 1.4"])
99
- s.add_dependency(%q<json>, [">= 1.2.0"])
100
- s.add_dependency(%q<backports>, [">= 0"])
101
- s.add_dependency(%q<webmock>, [">= 0"])
102
- s.add_dependency(%q<rspec>, [">= 0"])
103
- s.add_dependency(%q<json>, [">= 0"])
104
- end
105
- else
106
- s.add_dependency(%q<rest-client>, [">= 1.4"])
107
- s.add_dependency(%q<json>, [">= 1.2.0"])
108
- s.add_dependency(%q<backports>, [">= 0"])
109
- s.add_dependency(%q<webmock>, [">= 0"])
110
- s.add_dependency(%q<rspec>, [">= 0"])
111
- s.add_dependency(%q<json>, [">= 0"])
112
- end
113
- end
114
-
@@ -1,120 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__)+'/spec_helper')
2
-
3
- include Restfully
4
- describe Collection do
5
- describe "general behaviour" do
6
- before do
7
- @uri = URI.parse('http://api.local/x/y/z')
8
- @collection = Collection.new(@uri, session=mock('session')).load(:body => JSON.parse(fixture("grid5000-sites.json")))
9
- @jobs_collection = Collection.new(@uri, session=mock('session')).load(:body => JSON.parse(fixture("grid5000-rennes-jobs.json")))
10
- end
11
- it "should be enumerable" do
12
- @collection.length.should == 9
13
- @collection.size.should == 9
14
- @collection.map{|site| site["uid"]}.sort.should == ["bordeaux", "grenoble", "lille", "lyon", "nancy", "orsay", "rennes", "sophia", "toulouse"]
15
- end
16
-
17
- it "should have a :total attribute" do
18
- @collection["total"].should == 9
19
- end
20
-
21
- it "should have a :offset attribute" do
22
- @collection["offset"].should == 0
23
- end
24
-
25
- it "should try to find the matching item in the collection when calling [] with a symbol" do
26
- rennes = @collection[:rennes]
27
- rennes.class.should == Restfully::Resource
28
- rennes['uid'].should == 'rennes'
29
- end
30
- it "should try to find the matching item in the collection when calling [] with a symbol" do
31
- job = @jobs_collection[:'319482']
32
- job.class.should == Restfully::Resource
33
- job['uid'].should == 319482
34
- end
35
- it "should make a direct request to collection_uri/resource_uid when calling [] and the searched item is not in the collection" do
36
- Restfully::Resource.should_receive(:new).with('http://api.local/x/y/z/not_in_the_collection', @collection.session).and_return(resource = mock("resource"))
37
- resource.should_receive(:load).and_return(resource)
38
- @collection[:not_in_the_collection].should == resource
39
- end
40
- it "should go through the 'next' links (if any) to search for the requested item" do
41
- body = JSON.parse(fixture("grid5000-rennes-jobs.json"))
42
- body["total"] = 20
43
- body1 = JSON.parse(fixture("grid5000-rennes-jobs.json"))
44
- body["total"] = 20
45
- body1["offset"] = 8
46
- body2 = JSON.parse(fixture("grid5000-rennes-jobs.json"))
47
- body["total"] = 20
48
- body2["offset"] = 16
49
- body2["items"][1]["uid"] = "18th item"
50
- collection = Collection.new(@uri, session = mock('session')).load(:body => body)
51
- session.should_receive(:get).with(@uri, :query => {:offset => 8, :limit => 200}).ordered.and_return(response = mock("response", :body => body1, :status => 200, :headers => {}))
52
- session.should_receive(:get).with(@uri, :query => {:offset => 16, :limit => 200}).ordered.and_return(response = mock("response", :body => body2, :status => 200, :headers => {}))
53
- collection.find{|item| item["uid"] == "18th item"}.should_not be_nil
54
- end
55
- it "should always return nil if the searched item is not in the collection" do
56
- Restfully::Resource.should_receive(:new).with('http://api.local/x/y/z/doesnotexist', @collection.session).and_return(resource = mock("resource"))
57
- resource.should_receive(:load).and_raise Restfully::HTTP::ClientError.new(mock("response", :body => "Not Found", :status => 404))
58
- @collection[:doesnotexist].should be_nil
59
- end
60
- end
61
-
62
- describe "populating collection" do
63
- before do
64
- @uri = "http://server.com/path/to/collection"
65
- @session = mock("session", :logger => Logger.new($stderr))
66
- @collection = Collection.new(@uri, @session)
67
- end
68
- it "should define links" do
69
- Link.should_receive(:new).with({"rel" => "self", "href" => "/path/to/collection"}).and_return(link1=mock("link1"))
70
- Link.should_receive(:new).with({"rel" => "member", "href" => "/path/to/member", "title" => "member_title"}).and_return(link2=mock("link2"))
71
- @collection.should_receive(:define_link).with(link1)
72
- @collection.should_receive(:define_link).with(link2)
73
- @collection.populate_object("links", [
74
- {"rel" => "self", "href" => "/path/to/collection"},
75
- {"rel" => "member", "href" => "/path/to/member", "title" => "member_title"}
76
- ])
77
- end
78
- it "should create a new resource for each item" do
79
- items = [
80
- {
81
- 'links' => [
82
- {'rel' => 'self', 'href' => '/grid5000/sites/rennes'},
83
- {'rel' => 'collection', 'href' => '/grid5000/sites/rennes/versions', 'title' => 'versions'}
84
- ],
85
- 'uid' => 'rennes'
86
- }
87
- ]
88
- @collection.populate_object("items", items)
89
- @collection.find{|i| i['uid'] == 'rennes'}.class.should == Restfully::Resource
90
- end
91
-
92
- it "should not initialize resources lacking a self link" do
93
- items = [
94
- {
95
- 'links' => [
96
- {'rel' => 'collection', 'href' => '/grid5000/sites/rennes/versions', 'resolvable' => false, 'title' => 'versions'}
97
- ],
98
- 'uid' => 'rennes'
99
- }
100
- ]
101
- @collection.populate_object("items", items)
102
- @collection.items.should be_empty
103
- end
104
- it "should store its properties in the internal hash" do
105
- @collection.populate_object("uid", "rennes")
106
- @collection.populate_object("list_of_values", [1,2,"whatever", {:x => :y}])
107
- @collection.populate_object("hash", {"a" => [1,2], "b" => "c"})
108
- @collection.properties.should == {
109
- "hash"=>{"a"=>[1, 2], "b"=>"c"},
110
- "list_of_values"=>[1, 2, "whatever", {:x=>:y}],
111
- "uid"=>"rennes"
112
- }
113
- @collection["uid"].should == "rennes"
114
- @collection["hash"].should == {"a"=>[1, 2], "b"=>"c"}
115
- @collection["list_of_values"].should == [1, 2, "whatever", {:x=>:y}]
116
- end
117
- end
118
-
119
-
120
- end
@@ -1,4 +0,0 @@
1
- base_uri: http://somewhere.net/x/y/z
2
- username: u
3
- password: p
4
- verbose: false
@@ -1,540 +0,0 @@
1
- {
2
- "items": [
3
- {
4
- "name": "Bordeaux",
5
- "latitude": 44.833333,
6
- "location": "Bordeaux, France",
7
- "security_contact": "bordeaux-staff@lists.grid5000.fr",
8
- "uid": "bordeaux",
9
- "type": "site",
10
- "user_support_contact": "bordeaux-staff@lists.grid5000.fr",
11
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
12
- "links": [
13
- {
14
- "href": "/grid5000/sites/bordeaux/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
15
- "title": "version",
16
- "rel": "member",
17
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
18
- },
19
- {
20
- "href": "/grid5000/sites/bordeaux/versions",
21
- "title": "versions",
22
- "rel": "collection",
23
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
24
- },
25
- {
26
- "href": "/grid5000/sites/bordeaux",
27
- "rel": "self",
28
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
29
- },
30
- {
31
- "href": "/grid5000/sites/bordeaux/clusters",
32
- "title": "clusters",
33
- "rel": "collection",
34
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
35
- },
36
- {
37
- "href": "/grid5000/sites/bordeaux/environments",
38
- "title": "environments",
39
- "rel": "collection",
40
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
41
- },
42
- {
43
- "href": "/grid5000",
44
- "rel": "parent",
45
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
46
- },
47
- {
48
- "href": "/grid5000/sites/bordeaux/status",
49
- "title": "status",
50
- "rel": "collection",
51
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
52
- }
53
- ],
54
- "description": "Grid5000 Bordeaux site",
55
- "longitude": -0.566667,
56
- "email_contact": "bordeaux-staff@lists.grid5000.fr",
57
- "web": "http://www.grid5000.fr/mediawiki/index.php/Bordeaux:Home",
58
- "sys_admin_contact": "bordeaux-staff@lists.grid5000.fr"
59
- },
60
- {
61
- "name": "Grenoble",
62
- "latitude": 45.1833,
63
- "location": "Grenoble, France",
64
- "security_contact": null,
65
- "uid": "grenoble",
66
- "type": "site",
67
- "user_support_contact": null,
68
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
69
- "links": [
70
- {
71
- "href": "/grid5000/sites/grenoble/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
72
- "title": "version",
73
- "rel": "member",
74
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
75
- },
76
- {
77
- "href": "/grid5000/sites/grenoble/versions",
78
- "title": "versions",
79
- "rel": "collection",
80
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
81
- },
82
- {
83
- "href": "/grid5000/sites/grenoble",
84
- "rel": "self",
85
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
86
- },
87
- {
88
- "href": "/grid5000/sites/grenoble/clusters",
89
- "title": "clusters",
90
- "rel": "collection",
91
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
92
- },
93
- {
94
- "href": "/grid5000/sites/grenoble/environments",
95
- "title": "environments",
96
- "rel": "collection",
97
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
98
- },
99
- {
100
- "href": "/grid5000",
101
- "rel": "parent",
102
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
103
- },
104
- {
105
- "href": "/grid5000/sites/grenoble/status",
106
- "title": "status",
107
- "rel": "collection",
108
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
109
- }
110
- ],
111
- "description": "",
112
- "longitude": 5.7167,
113
- "email_contact": null,
114
- "web": null,
115
- "sys_admin_contact": null
116
- },
117
- {
118
- "name": "Lille",
119
- "latitude": 50.65,
120
- "location": "Lille, France",
121
- "security_contact": null,
122
- "uid": "lille",
123
- "type": "site",
124
- "user_support_contact": null,
125
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
126
- "links": [
127
- {
128
- "href": "/grid5000/sites/lille/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
129
- "title": "version",
130
- "rel": "member",
131
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
132
- },
133
- {
134
- "href": "/grid5000/sites/lille/versions",
135
- "title": "versions",
136
- "rel": "collection",
137
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
138
- },
139
- {
140
- "href": "/grid5000/sites/lille",
141
- "rel": "self",
142
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
143
- },
144
- {
145
- "href": "/grid5000/sites/lille/clusters",
146
- "title": "clusters",
147
- "rel": "collection",
148
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
149
- },
150
- {
151
- "href": "/grid5000/sites/lille/environments",
152
- "title": "environments",
153
- "rel": "collection",
154
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
155
- },
156
- {
157
- "href": "/grid5000",
158
- "rel": "parent",
159
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
160
- },
161
- {
162
- "href": "/grid5000/sites/lille/status",
163
- "title": "status",
164
- "rel": "collection",
165
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
166
- }
167
- ],
168
- "description": "",
169
- "longitude": 3.0833,
170
- "email_contact": null,
171
- "web": null,
172
- "sys_admin_contact": null
173
- },
174
- {
175
- "name": "Lyon",
176
- "latitude": 45.7667,
177
- "location": "Lyon, France",
178
- "security_contact": null,
179
- "uid": "lyon",
180
- "type": "site",
181
- "user_support_contact": null,
182
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
183
- "links": [
184
- {
185
- "href": "/grid5000/sites/lyon/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
186
- "title": "version",
187
- "rel": "member",
188
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
189
- },
190
- {
191
- "href": "/grid5000/sites/lyon/versions",
192
- "title": "versions",
193
- "rel": "collection",
194
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
195
- },
196
- {
197
- "href": "/grid5000/sites/lyon",
198
- "rel": "self",
199
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
200
- },
201
- {
202
- "href": "/grid5000/sites/lyon/clusters",
203
- "title": "clusters",
204
- "rel": "collection",
205
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
206
- },
207
- {
208
- "href": "/grid5000/sites/lyon/environments",
209
- "title": "environments",
210
- "rel": "collection",
211
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
212
- },
213
- {
214
- "href": "/grid5000",
215
- "rel": "parent",
216
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
217
- },
218
- {
219
- "href": "/grid5000/sites/lyon/status",
220
- "title": "status",
221
- "rel": "collection",
222
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
223
- }
224
- ],
225
- "description": "",
226
- "longitude": 4.8333,
227
- "email_contact": null,
228
- "web": null,
229
- "sys_admin_contact": null
230
- },
231
- {
232
- "name": "Nancy",
233
- "latitude": 48.7,
234
- "location": "Nancy, France",
235
- "security_contact": null,
236
- "uid": "nancy",
237
- "type": "site",
238
- "user_support_contact": null,
239
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
240
- "links": [
241
- {
242
- "href": "/grid5000/sites/nancy/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
243
- "title": "version",
244
- "rel": "member",
245
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
246
- },
247
- {
248
- "href": "/grid5000/sites/nancy/versions",
249
- "title": "versions",
250
- "rel": "collection",
251
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
252
- },
253
- {
254
- "href": "/grid5000/sites/nancy",
255
- "rel": "self",
256
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
257
- },
258
- {
259
- "href": "/grid5000/sites/nancy/clusters",
260
- "title": "clusters",
261
- "rel": "collection",
262
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
263
- },
264
- {
265
- "href": "/grid5000/sites/nancy/environments",
266
- "title": "environments",
267
- "rel": "collection",
268
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
269
- },
270
- {
271
- "href": "/grid5000",
272
- "rel": "parent",
273
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
274
- },
275
- {
276
- "href": "/grid5000/sites/nancy/status",
277
- "title": "status",
278
- "rel": "collection",
279
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
280
- }
281
- ],
282
- "description": "",
283
- "longitude": 6.2,
284
- "web": null,
285
- "sys_admin_contact": null
286
- },
287
- {
288
- "name": "Orsay",
289
- "latitude": 48.7,
290
- "location": "Orsay, France",
291
- "security_contact": null,
292
- "uid": "orsay",
293
- "type": "site",
294
- "user_support_contact": null,
295
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
296
- "links": [
297
- {
298
- "href": "/grid5000/sites/orsay/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
299
- "title": "version",
300
- "rel": "member",
301
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
302
- },
303
- {
304
- "href": "/grid5000/sites/orsay/versions",
305
- "title": "versions",
306
- "rel": "collection",
307
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
308
- },
309
- {
310
- "href": "/grid5000/sites/orsay",
311
- "rel": "self",
312
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
313
- },
314
- {
315
- "href": "/grid5000/sites/orsay/clusters",
316
- "title": "clusters",
317
- "rel": "collection",
318
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
319
- },
320
- {
321
- "href": "/grid5000/sites/orsay/environments",
322
- "title": "environments",
323
- "rel": "collection",
324
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
325
- },
326
- {
327
- "href": "/grid5000",
328
- "rel": "parent",
329
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
330
- },
331
- {
332
- "href": "/grid5000/sites/orsay/status",
333
- "title": "status",
334
- "rel": "collection",
335
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
336
- }
337
- ],
338
- "description": "",
339
- "longitude": 2.2,
340
- "email_contact": null,
341
- "web": null,
342
- "sys_admin_contact": null
343
- },
344
- {
345
- "name": "Rennes",
346
- "latitude": 48.1,
347
- "location": "Rennes, France",
348
- "security_contact": "rennes-staff@lists.grid5000.fr",
349
- "uid": "rennes",
350
- "type": "site",
351
- "user_support_contact": "rennes-staff@lists.grid5000.fr",
352
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
353
- "links": [
354
- {
355
- "href": "/grid5000/sites/rennes/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
356
- "title": "version",
357
- "rel": "member",
358
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
359
- },
360
- {
361
- "href": "/grid5000/sites/rennes/versions",
362
- "title": "versions",
363
- "rel": "collection",
364
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
365
- },
366
- {
367
- "href": "/grid5000/sites/rennes",
368
- "rel": "self",
369
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
370
- },
371
- {
372
- "href": "/grid5000/sites/rennes/clusters",
373
- "title": "clusters",
374
- "rel": "collection",
375
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
376
- },
377
- {
378
- "href": "/grid5000/sites/rennes/environments",
379
- "title": "environments",
380
- "rel": "collection",
381
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
382
- },
383
- {
384
- "href": "/grid5000",
385
- "rel": "parent",
386
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
387
- },
388
- {
389
- "href": "/grid5000/sites/rennes/status",
390
- "title": "status",
391
- "rel": "collection",
392
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
393
- }
394
- ],
395
- "description": "",
396
- "longitude": -1.6667,
397
- "compilation_server": false,
398
- "email_contact": "rennes-staff@lists.grid5000.fr",
399
- "web": "http://www.irisa.fr",
400
- "sys_admin_contact": "rennes-staff@lists.grid5000.fr"
401
- },
402
- {
403
- "name": "Sophia-Antipolis",
404
- "latitude": 43.6161,
405
- "location": "Sophia-Antipolis, France",
406
- "security_contact": "sophia-staff@lists.grid5000.fr",
407
- "uid": "sophia",
408
- "type": "site",
409
- "user_support_contact": "sophia-staff@lists.grid5000.fr",
410
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
411
- "links": [
412
- {
413
- "href": "/grid5000/sites/sophia/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
414
- "title": "version",
415
- "rel": "member",
416
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
417
- },
418
- {
419
- "href": "/grid5000/sites/sophia/versions",
420
- "title": "versions",
421
- "rel": "collection",
422
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
423
- },
424
- {
425
- "href": "/grid5000/sites/sophia",
426
- "rel": "self",
427
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
428
- },
429
- {
430
- "href": "/grid5000/sites/sophia/clusters",
431
- "title": "clusters",
432
- "rel": "collection",
433
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
434
- },
435
- {
436
- "href": "/grid5000/sites/sophia/environments",
437
- "title": "environments",
438
- "rel": "collection",
439
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
440
- },
441
- {
442
- "href": "/grid5000",
443
- "rel": "parent",
444
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
445
- },
446
- {
447
- "href": "/grid5000/sites/sophia/status",
448
- "title": "status",
449
- "rel": "collection",
450
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
451
- }
452
- ],
453
- "description": "",
454
- "longitude": 7.0678,
455
- "compilation_server": true,
456
- "email_contact": "sophia-staff@lists.grid5000.fr",
457
- "web": null,
458
- "sys_admin_contact": "sophia-staff@lists.grid5000.fr"
459
- },
460
- {
461
- "name": "Toulouse",
462
- "latitude": 43.6167,
463
- "location": "Toulouse, France",
464
- "security_contact": null,
465
- "uid": "toulouse",
466
- "type": "site",
467
- "user_support_contact": null,
468
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
469
- "links": [
470
- {
471
- "href": "/grid5000/sites/toulouse/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
472
- "title": "version",
473
- "rel": "member",
474
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
475
- },
476
- {
477
- "href": "/grid5000/sites/toulouse/versions",
478
- "title": "versions",
479
- "rel": "collection",
480
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
481
- },
482
- {
483
- "href": "/grid5000/sites/toulouse",
484
- "rel": "self",
485
- "type": "application/vnd.fr.grid5000.api.Site+json;level=1"
486
- },
487
- {
488
- "href": "/grid5000/sites/toulouse/clusters",
489
- "title": "clusters",
490
- "rel": "collection",
491
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
492
- },
493
- {
494
- "href": "/grid5000/sites/toulouse/environments",
495
- "title": "environments",
496
- "rel": "collection",
497
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
498
- },
499
- {
500
- "href": "/grid5000",
501
- "rel": "parent",
502
- "type": "application/vnd.fr.grid5000.api.Grid+json;level=1"
503
- },
504
- {
505
- "href": "/grid5000/sites/toulouse/status",
506
- "title": "status",
507
- "rel": "collection",
508
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
509
- }
510
- ],
511
- "description": "",
512
- "longitude": 1.4333,
513
- "email_contact": null,
514
- "web": null,
515
- "sys_admin_contact": null
516
- }
517
- ],
518
- "total": 9,
519
- "version": "4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
520
- "links": [
521
- {
522
- "href": "/grid5000/sites/versions/4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
523
- "title": "version",
524
- "rel": "member",
525
- "type": "application/vnd.fr.grid5000.api.Version+json;level=1"
526
- },
527
- {
528
- "href": "/grid5000/sites/versions",
529
- "title": "versions",
530
- "rel": "collection",
531
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
532
- },
533
- {
534
- "href": "/grid5000/sites",
535
- "rel": "self",
536
- "type": "application/vnd.fr.grid5000.api.Collection+json;level=1"
537
- }
538
- ],
539
- "offset": 0
540
- }