omf_sfa 0.1.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.
- data/.gitignore +24 -0
- data/Gemfile +6 -0
- data/README.md +211 -0
- data/Rakefile +23 -0
- data/bin/parse_rspec.rb +167 -0
- data/etc/omf-sfa/omf-sfa-am.yaml +12 -0
- data/examples/exogeni5nodemanifest.rspec +105 -0
- data/examples/instageni5nodemanifest.rspec +150 -0
- data/lib/omf-sfa/am/am-rest/REST_API.md +301 -0
- data/lib/omf-sfa/am/am-rest/account_handler.rb +145 -0
- data/lib/omf-sfa/am/am-rest/am_rest_server.rb +255 -0
- data/lib/omf-sfa/am/am-rest/api_template.html +48 -0
- data/lib/omf-sfa/am/am-rest/config.ru +110 -0
- data/lib/omf-sfa/am/am-rest/resource_handler.rb +178 -0
- data/lib/omf-sfa/am/am-rest/rest_handler.rb +573 -0
- data/lib/omf-sfa/am/am-rest/session_authenticator.rb +130 -0
- data/lib/omf-sfa/am/am-rpc/abstract_rpc_service.rb +60 -0
- data/lib/omf-sfa/am/am-rpc/am_authorizer.rb +161 -0
- data/lib/omf-sfa/am/am-rpc/am_rpc_api.rb +450 -0
- data/lib/omf-sfa/am/am-rpc/am_rpc_service.rb +402 -0
- data/lib/omf-sfa/am/am_liaison.rb +93 -0
- data/lib/omf-sfa/am/am_manager.rb +859 -0
- data/lib/omf-sfa/am/am_runner.rb +108 -0
- data/lib/omf-sfa/am/am_scheduler.rb +146 -0
- data/lib/omf-sfa/am/am_server.rb +194 -0
- data/lib/omf-sfa/am/config.ru +122 -0
- data/lib/omf-sfa/am/credential.rb +145 -0
- data/lib/omf-sfa/am/default_authorizer.rb +44 -0
- data/lib/omf-sfa/am/privilege_credential.rb +76 -0
- data/lib/omf-sfa/am/signature.rb +37 -0
- data/lib/omf-sfa/am/user_credential.rb +56 -0
- data/lib/omf-sfa/am.rb +7 -0
- data/lib/omf-sfa/model/abstract_prop_description.rb +87 -0
- data/lib/omf-sfa/model/model_class_description.rb +145 -0
- data/lib/omf-sfa/model/model_data_prop_description.rb +28 -0
- data/lib/omf-sfa/model/model_obj_prop_description.rb +49 -0
- data/lib/omf-sfa/model/ontology.rb +169 -0
- data/lib/omf-sfa/resource/README.md +24 -0
- data/lib/omf-sfa/resource/channel.rb +49 -0
- data/lib/omf-sfa/resource/comp_group.rb +41 -0
- data/lib/omf-sfa/resource/component_lease.rb +10 -0
- data/lib/omf-sfa/resource/constants.rb +24 -0
- data/lib/omf-sfa/resource/group_component.rb +35 -0
- data/lib/omf-sfa/resource/group_membership.rb +17 -0
- data/lib/omf-sfa/resource/gurn.rb +187 -0
- data/lib/omf-sfa/resource/interface.rb +78 -0
- data/lib/omf-sfa/resource/ip.rb +48 -0
- data/lib/omf-sfa/resource/link.rb +29 -0
- data/lib/omf-sfa/resource/node.rb +75 -0
- data/lib/omf-sfa/resource/oaccount.rb +94 -0
- data/lib/omf-sfa/resource/ocomponent.rb +134 -0
- data/lib/omf-sfa/resource/ogroup.rb +106 -0
- data/lib/omf-sfa/resource/olease.rb +61 -0
- data/lib/omf-sfa/resource/oproperty.rb +178 -0
- data/lib/omf-sfa/resource/oreference.rb +15 -0
- data/lib/omf-sfa/resource/oresource.rb +491 -0
- data/lib/omf-sfa/resource/project.rb +28 -0
- data/lib/omf-sfa/resource/project_membership.rb +13 -0
- data/lib/omf-sfa/resource/sfa_base.rb +544 -0
- data/lib/omf-sfa/resource/user.rb +25 -0
- data/lib/omf-sfa/resource.rb +20 -0
- data/lib/omf-sfa/util/create_sample_testbed.rb +68 -0
- data/lib/omf-sfa/util/load_from_sfa_xml.rb +65 -0
- data/lib/omf-sfa/version.rb +4 -0
- data/lib/omf_sfa.rb +5 -0
- data/omf_sfa.gemspec +46 -0
- data/owl/README +3 -0
- data/owl/ben-6509.rdf +1377 -0
- data/owl/ben-dell.rdf +586 -0
- data/owl/ben-dtn.rdf +1698 -0
- data/owl/ben.rdf +1335 -0
- data/owl/collections.owl +309 -0
- data/owl/compute.owl +1486 -0
- data/owl/domain.owl +444 -0
- data/owl/dtn.owl +1165 -0
- data/owl/ec2.owl +385 -0
- data/owl/ethernet.owl +466 -0
- data/owl/eucalyptus.owl +431 -0
- data/owl/id-mp-Request1.rdf +247 -0
- data/owl/itu-grid.owl +147 -0
- data/owl/kansei.owl +511 -0
- data/owl/layer.owl +645 -0
- data/owl/location.owl +117 -0
- data/owl/mass.rdf +608 -0
- data/owl/nlr.rdf +901 -0
- data/owl/orca.owl +181 -0
- data/owl/planetlab.owl +124 -0
- data/owl/protogeni.owl +467 -0
- data/owl/request-6509-2.rdf +150 -0
- data/owl/request-6509-3.rdf +158 -0
- data/owl/request-6509.rdf +199 -0
- data/owl/request.owl +222 -0
- data/owl/storage.owl +511 -0
- data/owl/topology.owl +608 -0
- data/schema/rspec-v3/ad-common.xsd +269 -0
- data/schema/rspec-v3/ad-reservation.rnc +12 -0
- data/schema/rspec-v3/ad-reservation.rng +28 -0
- data/schema/rspec-v3/ad-reservation.xsd +13 -0
- data/schema/rspec-v3/ad.rnc +151 -0
- data/schema/rspec-v3/ad.xsd +77 -0
- data/schema/rspec-v3/any-extension-schema.xsd +38 -0
- data/schema/rspec-v3/any-extension.rnc +30 -0
- data/schema/rspec-v3/common.rnc +185 -0
- data/schema/rspec-v3/manifest-common.xsd +244 -0
- data/schema/rspec-v3/manifest-request.xsd +95 -0
- data/schema/rspec-v3/manifest.rnc +62 -0
- data/schema/rspec-v3/manifest.xsd +34 -0
- data/schema/rspec-v3/request-common.xsd +219 -0
- data/schema/rspec-v3/request-reservation.rnc +12 -0
- data/schema/rspec-v3/request-reservation.xsd +13 -0
- data/schema/rspec-v3/request.rnc +118 -0
- data/schema/rspec-v3/request.xsd +94 -0
- data/share/assets/css/default.css +147 -0
- data/share/assets/css/rest_api.css +0 -0
- data/share/assets/network.html +28 -0
- data/share/assets/network.js +82 -0
- data/spec/am/am-rest/common.rb +29 -0
- data/spec/am/am-rest/resource_group_handler_XspecX.rb +97 -0
- data/spec/am/am-rest/resource_handler_spec.rb +204 -0
- data/spec/am/am-rpc/sfa_methods_spec.rb +150 -0
- data/spec/am/am_manager_spec.rb +307 -0
- data/spec/am/am_scheduler_spec.rb +57 -0
- data/spec/am/common.rb +24 -0
- data/spec/resource/common.rb +31 -0
- data/spec/resource/node_spec.rb +171 -0
- data/spec/resource/oaccount_spec.rb +92 -0
- data/spec/resource/ocomponent_spec.rb +225 -0
- data/spec/resource/ogroup_spec.rb +93 -0
- data/spec/resource/oresource_spec.rb +208 -0
- data/spec/resource_and_leases_spec.rb +377 -0
- data/test/OLD_FILES/assertion1.xml +117 -0
- data/test/OLD_FILES/greeter_spec.rb +15 -0
- data/test/OLD_FILES/mongo_test.rb +45 -0
- data/test/OLD_FILES/req-sfa-2.xml +6 -0
- data/test/OLD_FILES/req-sfa-g.xml +8 -0
- data/test/OLD_FILES/req-sfa-g2.xml +10 -0
- data/test/OLD_FILES/req-sfa-g3.xml +14 -0
- data/test/OLD_FILES/req-sfa.xml +6 -0
- data/test/OLD_FILES/req1.xml +22 -0
- data/test/OLD_FILES/req1b.xml +15 -0
- data/test/OLD_FILES/rspec-test.xml +1867 -0
- data/test/OLD_FILES/test.rb +67 -0
- data/test/OLD_FILES/test2.rb +32 -0
- data/test/am/am_manager_rspec_tests.rb +378 -0
- data/test/am/am_manager_tests.rb +518 -0
- data/test/am/am_scheduler_tests.rb +173 -0
- data/test/resource/olease_test.rb +74 -0
- data/test/sfa_requests/request.xml +5 -0
- data/test/sfa_requests/request1.xml +5 -0
- data/test/sfa_requests/request2.xml +5 -0
- data/test/sfa_requests/request3.xml +5 -0
- metadata +601 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'dm-core'
|
|
3
|
+
require 'dm-types'
|
|
4
|
+
require 'dm-validations'
|
|
5
|
+
require 'omf_base/lobject'
|
|
6
|
+
require 'set'
|
|
7
|
+
require 'active_support/inflector'
|
|
8
|
+
|
|
9
|
+
#require 'omf-sfa/resource/oproperty'
|
|
10
|
+
autoload :OProperty, 'omf-sfa/resource/oproperty'
|
|
11
|
+
#require 'omf-sfa/resource/group_membership'
|
|
12
|
+
autoload :GroupMembership, 'omf-sfa/resource/group_membership'
|
|
13
|
+
autoload :OAccount, 'omf-sfa/resource/oaccount'
|
|
14
|
+
autoload :OGroup, 'omf-sfa/resource/ogroup'
|
|
15
|
+
autoload :OLease, 'omf-sfa/resource/olease'
|
|
16
|
+
|
|
17
|
+
# module OMF::SFA::Resource
|
|
18
|
+
# class OResource; end
|
|
19
|
+
# end
|
|
20
|
+
#require 'omf-sfa/resource/oaccount'
|
|
21
|
+
|
|
22
|
+
module OMF::SFA::Resource
|
|
23
|
+
|
|
24
|
+
# This is the basic resource from which all other
|
|
25
|
+
# resources descend.
|
|
26
|
+
#
|
|
27
|
+
# Note: Can't call it 'Resource' to avoid any confusion
|
|
28
|
+
# with DataMapper::Resource
|
|
29
|
+
#
|
|
30
|
+
class OResource
|
|
31
|
+
include OMF::Base::Loggable
|
|
32
|
+
extend OMF::Base::Loggable
|
|
33
|
+
|
|
34
|
+
include DataMapper::Resource
|
|
35
|
+
include DataMapper::Validations
|
|
36
|
+
|
|
37
|
+
#@@default_href_prefix = 'http://somehost/resources/'
|
|
38
|
+
@@default_href_prefix = '/resources'
|
|
39
|
+
@@href_resolvers = {}
|
|
40
|
+
|
|
41
|
+
@@oprops = {}
|
|
42
|
+
|
|
43
|
+
# managing dm object
|
|
44
|
+
property :id, Serial
|
|
45
|
+
property :type, Discriminator
|
|
46
|
+
|
|
47
|
+
property :uuid, UUID
|
|
48
|
+
property :name, String
|
|
49
|
+
#property :href, String, :length => 255, :default => lambda {|r, m| r.def_href() }
|
|
50
|
+
property :urn, String, :length => 255
|
|
51
|
+
property :resource_type, String
|
|
52
|
+
|
|
53
|
+
has n, :o_properties, 'OProperty'
|
|
54
|
+
alias oproperties o_properties
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
#has n, :contained_in_groups, :model => :Group, :through => GroupMembership
|
|
58
|
+
#has n, :contained_in_groups, 'Group' #, :through => :group_membership #GroupMembership
|
|
59
|
+
|
|
60
|
+
#has n, :group_memberships
|
|
61
|
+
#has n, :groups, 'Group', :through => :group_membership #, :via => :groups
|
|
62
|
+
|
|
63
|
+
has n, :group_memberships, :child_key => [ :o_resource_id ]
|
|
64
|
+
has n, :included_in_groups, 'OGroup', :through => :group_memberships, :via => :o_group
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
#belongs_to :account, :model => 'OAccount', :child_key => [ :account_id ], :required => false
|
|
68
|
+
|
|
69
|
+
def self.href_resolver(&block)
|
|
70
|
+
@@href_resolvers[self] = block
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.oproperty(name, type, opts = {})
|
|
74
|
+
name = name.to_s
|
|
75
|
+
|
|
76
|
+
# should check if +name+ is already used
|
|
77
|
+
op = @@oprops[self] ||= {}
|
|
78
|
+
opts[:__type__] = type
|
|
79
|
+
|
|
80
|
+
if opts[:functional] == false
|
|
81
|
+
# property is an array
|
|
82
|
+
pname = DataMapper::Inflector.pluralize(name)
|
|
83
|
+
op[pname] = opts
|
|
84
|
+
|
|
85
|
+
define_method pname do
|
|
86
|
+
res = oproperty_get(pname)
|
|
87
|
+
if res == nil
|
|
88
|
+
oproperty_set(pname, [])
|
|
89
|
+
# We make a oproperty_get in order to get the extended Array with
|
|
90
|
+
# the overidden '<<' method. Check module ArrayProxy in oproperty.rb
|
|
91
|
+
res = oproperty_get(pname)
|
|
92
|
+
end
|
|
93
|
+
#puts "PROPERTY_GET(#{pname}) #{res}"
|
|
94
|
+
if rev_m = opts[:inverse]
|
|
95
|
+
res.on_modified do |v, added|
|
|
96
|
+
if added
|
|
97
|
+
if v.respond_to?(m = "#{rev_m}_add".to_sym)
|
|
98
|
+
v.send(m, self)
|
|
99
|
+
elsif v.respond_to?(m = "#{rev_m}=".to_sym)
|
|
100
|
+
v.send(m, self)
|
|
101
|
+
else
|
|
102
|
+
raise "Can't find any setter '#{rev_m}' on '#{v}'"
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
# TODO: should remove this one form the reverse side
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
if sf = opts[:set_filter]
|
|
110
|
+
res.on_set do |v|
|
|
111
|
+
self.send(sf, v)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
res
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Add method to add a single element to a non-functional property. This
|
|
118
|
+
# helps other entities to learn if this property is functional or not.
|
|
119
|
+
#
|
|
120
|
+
define_method "#{pname}_add" do |v|
|
|
121
|
+
self.send(pname.to_sym) << v
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
define_method "#{pname}=" do |v|
|
|
125
|
+
unless v.is_a? Array
|
|
126
|
+
raise "Property '#{pname}' in '#{self.class}' requires an Array in setter - #{v.inspect}"
|
|
127
|
+
end
|
|
128
|
+
res = self.send(pname.to_sym)
|
|
129
|
+
res.clear # clear any old values
|
|
130
|
+
v.each {|it| res << it }
|
|
131
|
+
res
|
|
132
|
+
end
|
|
133
|
+
else
|
|
134
|
+
op[name] = opts
|
|
135
|
+
|
|
136
|
+
define_method name do
|
|
137
|
+
res = oproperty_get(name)
|
|
138
|
+
if res.nil?
|
|
139
|
+
res = opts[:default]
|
|
140
|
+
if res.nil? && (self.respond_to?(m = "default_#{name}".to_sym))
|
|
141
|
+
res = send(m)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
res
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
define_method "#{name}=" do |v|
|
|
148
|
+
if sf = opts[:set_filter]
|
|
149
|
+
v = self.send(sf, v)
|
|
150
|
+
end
|
|
151
|
+
return if (old = oproperty_get(name)) == v
|
|
152
|
+
oproperty_set(name, v)
|
|
153
|
+
if rev_m = opts[:inverse]
|
|
154
|
+
if v
|
|
155
|
+
if v.respond_to?(m = "#{rev_m}_add".to_sym)
|
|
156
|
+
v.send(m, self)
|
|
157
|
+
elsif v.respond_to?(m = "#{rev_m}=".to_sym)
|
|
158
|
+
v.send(m, self)
|
|
159
|
+
else
|
|
160
|
+
raise "Can't find any setter '#{rev_m}' on '#{v}'"
|
|
161
|
+
end
|
|
162
|
+
else
|
|
163
|
+
# TODO: should remove this one form the reverse side
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Clone this resource this resource. However, the clone will have a unique UUID
|
|
172
|
+
#
|
|
173
|
+
def clone()
|
|
174
|
+
clone = self.class.new
|
|
175
|
+
attributes.each do |k, v|
|
|
176
|
+
next if k == :id || k == :uuid
|
|
177
|
+
clone.attribute_set(k, DataMapper::Ext.try_dup(v))
|
|
178
|
+
end
|
|
179
|
+
oproperties.each do |p|
|
|
180
|
+
clone.oproperty_set(p.name, DataMapper::Ext.try_dup(p.value))
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
clone.uuid = UUIDTools::UUID.random_create
|
|
184
|
+
return clone
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def uuid()
|
|
188
|
+
unless uuid = attribute_get(:uuid)
|
|
189
|
+
uuid = self.uuid = UUIDTools::UUID.random_create
|
|
190
|
+
end
|
|
191
|
+
uuid
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def href(opts = {})
|
|
195
|
+
klass = self.class
|
|
196
|
+
while (resolver = @@href_resolvers[klass]).nil?
|
|
197
|
+
break if (klass = klass.superclass) == Object
|
|
198
|
+
end
|
|
199
|
+
if resolver
|
|
200
|
+
href = resolver.call(self, opts)
|
|
201
|
+
end
|
|
202
|
+
unless href
|
|
203
|
+
href = "/resources/#{self.uuid.to_s}"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# if prefix = opts[:name_prefix]
|
|
207
|
+
# href = "#{prefix}/#{self.name || self.uuid.to_s}"
|
|
208
|
+
# elsif opts[:href_use_class_prefix]
|
|
209
|
+
# #href = "/#{self.resource_type}/#{self.name || self.uuid.to_s}"
|
|
210
|
+
# href = "/#{self.resource_type.pluralize}/#{self.uuid.to_s}"
|
|
211
|
+
# elsif prefix = opts[:href_prefix] || @@default_href_prefix
|
|
212
|
+
# href = "#{prefix}/#{self.uuid.to_s}"
|
|
213
|
+
# end
|
|
214
|
+
href
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def resource_type()
|
|
218
|
+
unless rt = attribute_get(:resource_type)
|
|
219
|
+
rt = self.class.to_s.split('::')[-1].downcase
|
|
220
|
+
end
|
|
221
|
+
rt
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# Return the status of the resource. Should be
|
|
226
|
+
# one of: _configuring_, _ready_, _failed_, and _unknown_
|
|
227
|
+
#
|
|
228
|
+
def status
|
|
229
|
+
'unknown'
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def oproperty(pname)
|
|
233
|
+
self.oproperties.first(:name => pname.to_sym)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def oproperty_get(pname)
|
|
238
|
+
#puts "OPROPERTY_GET: pname:'#{pname}'"
|
|
239
|
+
pname = pname.to_sym
|
|
240
|
+
return self.name if pname == :name
|
|
241
|
+
|
|
242
|
+
prop = self.oproperties.first(:name => pname)
|
|
243
|
+
prop.nil? ? nil : prop.value
|
|
244
|
+
end
|
|
245
|
+
alias_method :[], :oproperty_get
|
|
246
|
+
|
|
247
|
+
def oproperty_set(pname, value, type = nil)
|
|
248
|
+
#puts "OPROPERTY_SET pname:'#{pname}', value:'#{value.class}'-#{type}, self:'#{self.inspect}'"
|
|
249
|
+
pname = pname.to_sym
|
|
250
|
+
if pname == :name
|
|
251
|
+
self.name = value
|
|
252
|
+
else
|
|
253
|
+
self.save
|
|
254
|
+
#puts ">>>>>" + @@oprops[self.class][pname.to_s].to_s
|
|
255
|
+
prop = self.oproperties.first_or_create(:name => pname)
|
|
256
|
+
prop.value = value
|
|
257
|
+
end
|
|
258
|
+
value
|
|
259
|
+
end
|
|
260
|
+
alias_method :[]=, :oproperty_set
|
|
261
|
+
|
|
262
|
+
def oproperties_as_hash
|
|
263
|
+
res = {}
|
|
264
|
+
oproperties.each do |p|
|
|
265
|
+
res[p.name] = p.value
|
|
266
|
+
end
|
|
267
|
+
res
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def each_resource(&block)
|
|
271
|
+
# resources don't contain other resources, groups do'
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# alias_method :_dirty_children?, :dirty_children?
|
|
275
|
+
# def dirty_children?
|
|
276
|
+
# puts "CHECKING CHILDREN DIRTY: #{_dirty_children?}"
|
|
277
|
+
# _dirty_children?
|
|
278
|
+
# end
|
|
279
|
+
|
|
280
|
+
alias_method :_dirty_self?, :dirty_self?
|
|
281
|
+
def dirty_self?
|
|
282
|
+
#puts "CHECKING DIRTY #{_dirty_self?}"
|
|
283
|
+
return true if _dirty_self?
|
|
284
|
+
o_properties.each do |p|
|
|
285
|
+
return true if p.dirty_self?
|
|
286
|
+
end
|
|
287
|
+
false
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# alias_method :_dirty_attributes, :dirty_attributes
|
|
291
|
+
# def dirty_attributes
|
|
292
|
+
# dirty = _dirty_attributes
|
|
293
|
+
# puts "DIRTY ATTRIBUTE #{dirty.inspect}"
|
|
294
|
+
# dirty
|
|
295
|
+
# end
|
|
296
|
+
|
|
297
|
+
# Return true if this resource is a Group
|
|
298
|
+
def group?
|
|
299
|
+
false
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# Remove this resource from all groups it currently belongs.
|
|
304
|
+
#
|
|
305
|
+
def remove_from_all_groups
|
|
306
|
+
self.group_memberships.each {|m| m.destroy}
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Add this resource and all contained to +set+.
|
|
310
|
+
def all_resources(set = Set.new)
|
|
311
|
+
set << self
|
|
312
|
+
set
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
before :save do
|
|
317
|
+
unless self.uuid
|
|
318
|
+
self.uuid = UUIDTools::UUID.random_create
|
|
319
|
+
end
|
|
320
|
+
unless self.name
|
|
321
|
+
self.name = self.urn ? GURN.create(self.urn).short_name : "r#{self.object_id}"
|
|
322
|
+
end
|
|
323
|
+
unless self.urn
|
|
324
|
+
# The purpose or function of a URN is to provide a globally unique,
|
|
325
|
+
# persistent identifier used for recognition, for access to
|
|
326
|
+
# characteristics of the resource or for access to the resource
|
|
327
|
+
# itself.
|
|
328
|
+
# source: http://tools.ietf.org/html/rfc1737
|
|
329
|
+
#
|
|
330
|
+
name = self.name
|
|
331
|
+
self.urn = GURN.create(name, :model => self.class).to_s
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def destroy
|
|
336
|
+
#debug "ORESOURCE destroy #{self}"
|
|
337
|
+
self.remove_from_all_groups
|
|
338
|
+
|
|
339
|
+
#if p = self.provided_by
|
|
340
|
+
# pa = p.provides
|
|
341
|
+
# pa.delete self
|
|
342
|
+
# r = p.save
|
|
343
|
+
# i = 0
|
|
344
|
+
#end
|
|
345
|
+
|
|
346
|
+
# first destroy all properties
|
|
347
|
+
self.oproperties.all().each do |p|
|
|
348
|
+
#debug "ORESOURCE destroying property '#{p.inspect}'"
|
|
349
|
+
r = p.destroy
|
|
350
|
+
r
|
|
351
|
+
end
|
|
352
|
+
#p = self.oproperties.all()
|
|
353
|
+
super
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def destroy!
|
|
357
|
+
#debug "ORESOURCE destroy! #{self}"
|
|
358
|
+
destroy
|
|
359
|
+
super
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def to_json(*a)
|
|
363
|
+
unless self.id
|
|
364
|
+
# need an id, means I haven't been saved yet
|
|
365
|
+
save
|
|
366
|
+
end
|
|
367
|
+
{
|
|
368
|
+
'json_class' => self.class.name,
|
|
369
|
+
'id' => self.id
|
|
370
|
+
}.to_json(*a)
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
def as_json(options = { })
|
|
374
|
+
{
|
|
375
|
+
"json_class" => self.class.name,
|
|
376
|
+
"id" => self.id
|
|
377
|
+
}
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
#def self.from_json(o)
|
|
382
|
+
# puts "FROM_JSON"
|
|
383
|
+
# klass = o['json_class']
|
|
384
|
+
# id = o['id']
|
|
385
|
+
# eval(klass).first(:id => id)
|
|
386
|
+
#end
|
|
387
|
+
|
|
388
|
+
def self.json_create(o)
|
|
389
|
+
klass = o['json_class']
|
|
390
|
+
id = o['id']
|
|
391
|
+
r = eval(klass).first(:id => id)
|
|
392
|
+
r
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def to_hash(objs = {}, opts = {})
|
|
396
|
+
max_level = opts[:max_level] ||= 0
|
|
397
|
+
level = opts[:level] ||= 0
|
|
398
|
+
if level > max_level
|
|
399
|
+
return self.href
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
#debug "to_hash(self):opts: #{opts.keys.inspect}::#{objs.keys.inspect}::"
|
|
403
|
+
h = to_hash_brief(opts)
|
|
404
|
+
return h if objs.key?(self)
|
|
405
|
+
objs[self] = true
|
|
406
|
+
return h if opts[:brief] || (level >= max_level)
|
|
407
|
+
|
|
408
|
+
opts = opts.merge(level: level + 1)
|
|
409
|
+
opts[:brief] = true if level > max_level
|
|
410
|
+
#puts ">>>> #{opts}"
|
|
411
|
+
to_hash_long(h, objs, opts)
|
|
412
|
+
h
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def to_hash_brief(opts = {})
|
|
416
|
+
h = {}
|
|
417
|
+
uuid = h[:uuid] = self.uuid.to_s
|
|
418
|
+
h[:href] = self.href
|
|
419
|
+
name = self.name
|
|
420
|
+
if name && ! name.start_with?('_')
|
|
421
|
+
h[:name] = self.name
|
|
422
|
+
end
|
|
423
|
+
h[:type] = self.resource_type
|
|
424
|
+
h
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def to_hash_long(h, objs = {}, opts = {})
|
|
428
|
+
_oprops_to_hash(h, objs, opts)
|
|
429
|
+
h
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def default_href_prefix
|
|
433
|
+
@@default_href_prefix
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def _oprops_to_hash(h, objs, opts)
|
|
437
|
+
klass = self.class
|
|
438
|
+
while klass
|
|
439
|
+
if op = @@oprops[klass]
|
|
440
|
+
op.each do |k, v|
|
|
441
|
+
k = k.to_sym
|
|
442
|
+
unless (value = send(k)).nil?
|
|
443
|
+
#puts "OPROPS_TO_HAHS(#{k}): #{value}::#{value.class}--#{oproperty_get(k)}"
|
|
444
|
+
#puts "OPROPS_TO_HAHS(#{k}): #{opts[:level]} >= #{opts[:max_level]}"
|
|
445
|
+
if value.is_a? OResource
|
|
446
|
+
href_only = opts[:level] >= opts[:max_level]
|
|
447
|
+
value = href_only ? value.href : value.to_hash(objs, opts)
|
|
448
|
+
#value = value.to_hash(objs, opts)
|
|
449
|
+
end
|
|
450
|
+
if value.is_a? Time
|
|
451
|
+
value = value.iso8601
|
|
452
|
+
end
|
|
453
|
+
if value.kind_of? Array
|
|
454
|
+
next if value.empty?
|
|
455
|
+
opts = opts.merge(level: opts[:level] + 1)
|
|
456
|
+
value = value.collect do |e|
|
|
457
|
+
#(e.kind_of? OResource) ? (href_only ? e.href : e.to_hash(objs, opts)) : e
|
|
458
|
+
(e.kind_of? OResource) ? e.to_hash(objs, opts) : e
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
h[k] = value
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
klass = klass.superclass
|
|
467
|
+
end
|
|
468
|
+
h
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
# Extend array to add functionality dealing with property values
|
|
473
|
+
#class PropValueArray < Array
|
|
474
|
+
|
|
475
|
+
# def to_json(*a)
|
|
476
|
+
# {
|
|
477
|
+
# 'json_class' => self.class.name,
|
|
478
|
+
# 'els' => self.to_a.to_json
|
|
479
|
+
# }.to_json(*a)
|
|
480
|
+
# end
|
|
481
|
+
|
|
482
|
+
# def self.json_create(o)
|
|
483
|
+
# # http://www.ruby-lang.org/en/news/2013/02/22/json-dos-cve-2013-0269/
|
|
484
|
+
# v = JSON.load(o['els'])
|
|
485
|
+
# v
|
|
486
|
+
# end
|
|
487
|
+
|
|
488
|
+
#end
|
|
489
|
+
|
|
490
|
+
end # OMF::SFA
|
|
491
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'omf-sfa/resource/oresource'
|
|
2
|
+
require 'omf-sfa/resource/project_membership'
|
|
3
|
+
require 'omf-sfa/resource/user'
|
|
4
|
+
|
|
5
|
+
module OMF::SFA::Resource
|
|
6
|
+
|
|
7
|
+
# This class represents a Project which is strictly connected to the notion of the Slice/Account
|
|
8
|
+
#
|
|
9
|
+
class Project < OResource
|
|
10
|
+
|
|
11
|
+
#has 1, :account, :model => 'OAccount', :required => false
|
|
12
|
+
oproperty :account, :account, :inverse => :project
|
|
13
|
+
|
|
14
|
+
oproperty :users, :user, :functional => false, :inverse => :projects
|
|
15
|
+
# has n, :project_memberships
|
|
16
|
+
# has n, :users, :through => :project_memberships, :via => :user
|
|
17
|
+
|
|
18
|
+
def to_hash_long(h, objs, opts = {})
|
|
19
|
+
super
|
|
20
|
+
href_only = opts[:level] >= opts[:max_level]
|
|
21
|
+
h[:users] = self.users.map do |p|
|
|
22
|
+
href_only ? p.href : p.to_hash(objs, opts)
|
|
23
|
+
end
|
|
24
|
+
h
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|