Class: OMF::SFA::AM::AMManager

Inherits:
Base::LObject
  • Object
show all
Defined in:
lib/omf-sfa/am/am_manager.rb

Overview

The manager is where all the AM related policies and resource management is concentrated. Testbeds with their own ways of dealing with resources and components should only need to extend this class.

Instance Method Summary collapse

Constructor Details

#initialize(scheduler) ⇒ AMManager

Create an instance of this manager

Parameters:

  • scheduler (Scheduler)

    to use for creating new resource



34
35
36
# File 'lib/omf-sfa/am/am_manager.rb', line 34

def initialize(scheduler)
  @scheduler = scheduler
end

Instance Method Details

#_get_nil_accountObject



853
854
855
# File 'lib/omf-sfa/am/am_manager.rb', line 853

def ()
  @scheduler.()
end

#close_account(account_descr, authorizer) ⇒ OAccount

Close the account described by account hash.

Make sure that all associated resources are freed as well

Parameters:

  • properties (Hash)

    of account

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/omf-sfa/am/am_manager.rb', line 174

def (, authorizer)
   = (, authorizer)
  authorizer.can_close_account?()
  # TODO: Free all resources associated with this account!!!!
  # OMF::SFA::Resource::OComponent.all(:account => account).each do |c|
  # c.account = def_account
  # c.save
  # end
  .close
  .save
  
end

#create_resource(resource_descr, type_to_create, oproperties, authorizer) ⇒ OResource

Create a resource

Parameters:

  • Describing (Hash)

    properties of the requested resource

  • Type (String)

    to create

  • A (Hash)

    hash with all the OProperty values of the requested resource

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



540
541
542
543
544
545
546
# File 'lib/omf-sfa/am/am_manager.rb', line 540

def create_resource(resource_descr, type_to_create, oproperties, authorizer)
  authorizer.can_create_resource?(resource_descr, type_to_create)
  unless resource = @scheduler.create_resource(resource_descr, type_to_create, oproperties, authorizer)
    raise UnknownResourceException.new "Resource '#{resource_descr.inspect}' cannot be created"
  end
  resource
end

#find_account(account_descr, authorizer) ⇒ OAccount

Return the account described by account_descr. Create if it doesn’t exist.

Parameters:

  • properties (Hash)

    of account

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



100
101
102
103
104
105
106
# File 'lib/omf-sfa/am/am_manager.rb', line 100

def (, authorizer)
  unless  = OMF::SFA::Resource::OAccount.first()
    raise UnavailableResourceException.new "Unknown account '#{.inspect}'"
  end
  authorizer.can_view_account?()
  
end

#find_active_account(account_descr, authorizer) ⇒ OAccount

Return the account described by account_descr if it is active.

Parameters:

  • properties (Hash)

    of account

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



136
137
138
139
140
141
142
# File 'lib/omf-sfa/am/am_manager.rb', line 136

def (, authorizer)
   = (, authorizer)
  if .closed?
    raise UnavailableResourceException.new "Account '#{.inspect}' is closed"
  end
  
end

#find_all_accounts(authorizer) ⇒ Array<OAccount>

Return all accounts visible to the requesting user

Parameters:

  • Defines (Authorizer)

    context for authorization decisions

Returns:

  • (Array<OAccount>)

    The visible accounts (maybe empty)



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/omf-sfa/am/am_manager.rb', line 113

def find_all_accounts(authorizer)
  accounts = OMF::SFA::Resource::OAccount.all()
   = ()
  accounts.map do |a|
    next if a == 
    begin
      authorizer.can_view_account?(a)
      a
    rescue InsufficientPrivilegesException
      nil
    end
  end.compact
end

#find_all_components_for_account(account, authorizer) ⇒ Array<OComponent>

Find all components for a specific account.

Parameters:

  • Account (OAccount)

    for which to find all associated component

  • Defines (Authorizer)

    context for authorization decisions

Returns:



497
498
499
500
501
502
503
504
505
506
507
# File 'lib/omf-sfa/am/am_manager.rb', line 497

def (, authorizer)
  res = OMF::SFA::Resource::OComponent.all(:account => )
  res.map do |r|
    begin
      authorizer.can_view_resource?(r)
      r
    rescue InsufficientPrivilegesException
      nil
    end
  end.compact
end

#find_all_leases(authorizer) ⇒ Object



294
295
296
297
298
299
300
301
302
303
304
# File 'lib/omf-sfa/am/am_manager.rb', line 294

def find_all_leases(authorizer)
  leases = OMF::SFA::Resource::OLease.all
  leases.map do |l|
    begin
      authorizer.can_view_lease?(l)
      l
    rescue InsufficientPrivilegesException
      nil
    end
  end.compact
end

#find_all_leases_for_account(account, authorizer) ⇒ Array<OLease>

Return all leases of the specified account

Parameters:

  • Account (OAccount)

    for which to find all associated leases

  • Defines (Authorizer)

    context for authorization decisions

Returns:

  • (Array<OLease>)

    The account’s leases (maybe empty)



281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/omf-sfa/am/am_manager.rb', line 281

def (, authorizer)
  debug "find_all_leases_for_account: account:'#{.inspect}' authorizer:'#{authorizer.inspect}'"
  leases = OMF::SFA::Resource::OLease.all(:account => )
  leases.map do |l|
    begin
      authorizer.can_view_lease?(l)
      l
    rescue InsufficientPrivilegesException
      nil
    end
  end.compact
end

#find_all_resources_for_account(account = _get_nil_account, authorizer) ⇒ Array<OResource>

Find all resources for a specific account.

Parameters:

  • Account (OAccount)

    for which to find all associated resources

  • Defines (Authorizer)

    context for authorization decisions

Returns:

  • (Array<OResource>)

    The resource requested



478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/omf-sfa/am/am_manager.rb', line 478

def ( = , authorizer)
  debug "find_all_resources_for_account: #{.inspect}"
  res = OMF::SFA::Resource::OResource.all(:account => )
  res.map do |r|
    begin
      authorizer.can_view_resource?(r)
      r
    rescue InsufficientPrivilegesException
      nil
    end
  end.compact
end

#find_lease(lease_descr, lease_oproperties, authorizer) ⇒ OLease

Return the lease described by lease_descr.

Parameters:

  • properties (Hash)

    of lease

  • lease (Hash)

    oproperties like “:valid_from” and “:valid_until”

  • Defines (Authorizer)

    context for authorization decisions

Returns:

  • (OLease)

    The requested lease

Raises:



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/omf-sfa/am/am_manager.rb', line 257

def find_lease(lease_descr, lease_oproperties, authorizer)
  if lease_oproperties.empty?
    lease = OMF::SFA::Resource::OLease.first(lease_descr)
    raise UnavailableResourceException.new "Unknown lease '#{lease_descr.inspect}'" if lease.nil?
    authorizer.can_view_lease?(lease)
    return lease
  end
  leases = OMF::SFA::Resource::OLease.all(lease_descr)
  leases.each do |l|
    if (l[:valid_from] == lease_oproperties[:valid_from] &&
        l[:valid_until] == lease_oproperties[:valid_until])
      authorizer.can_view_lease?(l)
      return l
    end
  end
  raise UnavailableResourceException.new "Unknown lease '#{lease_descr.inspect}'"
end

#find_or_create_account(account_descr, authorizer) ⇒ OAccount

Return the account described by account_descr. Create if it doesn’t exist.

Parameters:

  • properties (Hash)

    of account

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/omf-sfa/am/am_manager.rb', line 76

def (, authorizer)
  debug "find_or_create_account: '#{.inspect}'"
  begin
    return (, authorizer)
  rescue UnavailableResourceException
  end
  authorizer.can_create_account?
   = OMF::SFA::Resource::OAccount.create()
  # We have an 1-to-1 relationship between account and project for the moment
  project = OMF::SFA::Resource::Project.create
  .project = project
  .save
  raise UnavailableResourceException.new "Cannot create '#{.inspect}'" unless 
  
end

#find_or_create_lease(lease_descr, lease_oproperties, authorizer) ⇒ OLease

Return the lease described by lease_descr. Create if it doesn’t exist.

Parameters:

  • lease_descr (Hash)

    properties of lease

  • lease (Hash)

    oproperties like “:valid_from” and “:valid_until”

  • Defines (Authorizer)

    context for authorization decisions

Returns:

  • (OLease)

    The requested lease

Raises:



236
237
238
239
240
241
242
243
244
245
246
# File 'lib/omf-sfa/am/am_manager.rb', line 236

def find_or_create_lease(lease_descr, lease_oproperties, authorizer)
  debug "find_or_create_lease: '#{lease_descr.inspect}', '#{lease_oproperties.inspect}'"
  begin
    return find_lease(lease_descr, lease_oproperties, authorizer)
  rescue UnavailableResourceException
  end
  unless lease_oproperties.has_key?(:valid_from) && lease_oproperties.has_key?(:valid_until)
    raise UnavailablePropertiesException.new "Cannot create lease without ':valid_from' and 'valid_until' oproperties #{lease_oproperties.inspect}"
  end
  lease = create_resource(lease_descr, 'OLease', lease_oproperties, authorizer)
end

#find_or_create_resource(resource_descr, type_to_create, oproperties, authorizer) ⇒ Array<OComponent>

Find all components

def find_all_components

res = OMF::SFA::Resource::OComponent.all
res

end

Returns:

  • (Array<OComponent>)

    The components requested



518
519
520
521
522
523
524
525
526
527
528
529
# File 'lib/omf-sfa/am/am_manager.rb', line 518

def find_or_create_resource(resource_descr, type_to_create, oproperties, authorizer)
  debug "find_or_create_resource: resource '#{resource_descr.inspect}' type: '#{type_to_create}'"
  unless resource_descr.is_a? Hash
    raise FormatException.new "Unknown resource description '#{resource_descr.inspect}'"
  end

  begin
    return find_resource(resource_descr, authorizer)
  rescue UnknownResourceException
  end
  create_resource(resource_descr, type_to_create, oproperties, authorizer)
end

#find_or_create_resource_for_account(resource_descr, type_to_create, oproperties, authorizer) ⇒ OResource

Find or create a resource for authorizer’s account. If it doesn’t exist, is already assigned to someone else, or cannot be created, throws UnknownResourceException.

Parameters:

  • describing (Hash)

    properties of the requested resource

  • Type (String)

    to create if not already exist

  • A (Hash)

    hash with all the OProperty values of the requested resource

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



559
560
561
562
563
564
# File 'lib/omf-sfa/am/am_manager.rb', line 559

def (resource_descr, type_to_create, oproperties, authorizer)
  debug "find_or_create_resource_for_account: r_descr:'#{resource_descr}' type:'#{type_to_create}' authorizer:'#{authorizer.inspect}'"
  rdescr = resource_descr.dup
  rdescr[:account] = authorizer.
  find_or_create_resource(rdescr, type_to_create, oproperties, authorizer)
end

#find_or_create_user(user_descr) ⇒ User

Return the user described by user_descr. Create if it doesn’t exist.

Note: This is an unprivileged operation as creating a user doesn’t imply anything else beyond opening a record.

Parameters:

  • properties (Hash)

    of user

Returns:

  • (User)

    The requested user

Raises:



198
199
200
201
202
203
204
205
206
207
# File 'lib/omf-sfa/am/am_manager.rb', line 198

def find_or_create_user(user_descr)
  debug "find_or_create_user: '#{user_descr.inspect}'"
  begin
    return find_user(user_descr)
  rescue UnavailableResourceException
  end
  user = OMF::SFA::Resource::User.create(user_descr)
  raise UnavailableResourceException.new "Cannot create '#{user_descr.inspect}'" unless user
  user
end

#find_resource(resource_descr, authorizer) ⇒ OResource

Note:

This will assign the resource automatically to the requesting account

Find a resource. If it doesn’t exist throws UnknownResourceException If it’s not visible to requester throws InsufficientPrivilegesException

Parameters:

  • describing (Hash, String, OResource)

    properties of the requested resource, or the resource’s UUID

  • If (Boolean)

    true, throw exception if not already assigned to requester

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# File 'lib/omf-sfa/am/am_manager.rb', line 427

def find_resource(resource_descr, authorizer)
  debug "find_resource: descr: '#{resource_descr.inspect}'"
  if resource_descr.kind_of? OMF::SFA::Resource::OResource
    resource = resource_descr
  elsif resource_descr.kind_of? Hash
    resource = OMF::SFA::Resource::OResource.first(resource_descr)
  elsif resource_descr.kind_of? String
    # assume to be UUID
    begin
      uuid = UUIDTools::UUID.parse(resource_descr)
      descr = {:uuid => uuid}
    rescue ArgumentError
      # doesn't seem to be a UUID, try it as a name - be aware of non-uniqueness
      descr = {:name => resource_descr}
    end
    resource = OMF::SFA::Resource::OResource.first(descr)
  else
    raise FormatException.new "Unknown resource description type '#{resource_descr.class}' (#{resource_descr})"
  end
  unless resource
    raise UnknownResourceException.new "Resource '#{resource_descr.inspect}' is not available or doesn't exist"
  end
  authorizer.can_view_resource?(resource)
  resource
end

#find_resource_for_account(resource_descr, authorizer) ⇒ OResource

Note:

This will assign the resource automatically to the requesting account

Find a resource which has been assigned to the authorizer’s account. If it doesn’t exist, or is not visible to requester throws UnknownResourceException.

Parameters:

  • describing (Hash, String)

    properties of the requested resource, or the resource’s UUID

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



465
466
467
468
469
# File 'lib/omf-sfa/am/am_manager.rb', line 465

def (resource_descr, authorizer)
  rdescr = resource_descr.dup
  rdescr[:account] = authorizer.
  find_resource(rdescr, authorizer)
end

#find_user(user_descr) ⇒ User

Return the user described by user_descr.

Note: This is an unprivileged operation as creating a user doesn’t imply anything else beyond opening a record.

Parameters:

  • properties (Hash)

    of user

Returns:

  • (User)

    The requested user

Raises:



218
219
220
221
222
223
# File 'lib/omf-sfa/am/am_manager.rb', line 218

def find_user(user_descr)
  unless user = OMF::SFA::Resource::User.first(user_descr)
    raise UnavailableResourceException.new "Unknown user '#{user_descr.inspect}'"
  end
  user
end

#manage_resource(resource) ⇒ Object

Register a resource to be managed by this AM.

Parameters:

  • resource (OResource)

    to have managed by this manager



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/omf-sfa/am/am_manager.rb', line 44

def manage_resource(resource)
  unless resource.is_a?(OMF::SFA::Resource::OResource)
    raise "Resource '#{resource}' needs to be of type 'OResource', but is '#{resource.class}'"
  end

   = 
  resource. = 
  resource.save
  # rg = get_root_group_for_account(def_account)
  # rg.contains_resources << resource
  # rg.save
  resource
end

#manage_resources(resources) ⇒ Object

Register an array of resources to be managed by this AM.

Parameters:

  • array (Array)

    of resources



62
63
64
# File 'lib/omf-sfa/am/am_manager.rb', line 62

def manage_resources(resources)
  resources.map {|r| manage_resource(r) }
end

#modify_lease(lease_oproperties, lease, authorizer) ⇒ OLease

Modify lease described by lease_descr hash

Parameters:

  • lease (Hash)

    oproperties like “:valid_from” and “:valid_until”

  • lease (OLease)

    to modify

  • Authorization (Authorizer)

    context

Returns:

  • (OLease)

    The requested lease



313
314
315
316
317
318
319
# File 'lib/omf-sfa/am/am_manager.rb', line 313

def modify_lease(lease_oproperties, lease, authorizer)
  authorizer.can_modify_lease?(lease)
  lease.valid_from = lease_oproperties[:valid_from]
  lease.valid_until = lease_oproperties[:valid_until]
  lease.save
  lease
end

#release_all_components_for_account(account, authorizer) ⇒ Object

This method finds all the components of the specific account and detaches them.

Parameters:

  • Account (OAccount)

    who owns the components

  • Authorization (Authorizer)

    context



789
790
791
792
# File 'lib/omf-sfa/am/am_manager.rb', line 789

def (, authorizer)
  components = (, authorizer)
  release_resources(components, authorizer)
end

#release_lease(lease, authorizer) ⇒ Object

cancel lease

This implementation simply frees the lease record.

Parameters:

  • lease (OLease)

    to release

  • Authorization (Authorizer)

    context



328
329
330
331
332
333
334
335
336
# File 'lib/omf-sfa/am/am_manager.rb', line 328

def release_lease(lease, authorizer)
  debug "release_lease: lease:'#{lease.inspect}' authorizer:'#{authorizer.inspect}'"
  authorizer.can_release_lease?(lease)

  lease.component_leases.each do |l|
    l.destroy # unlink the lease with the corresponding components
  end
  lease.status = :cancelled
end

#release_resource(resource, authorizer) ⇒ Object

Release ‘resource’.

This implementation simply frees the resource record.

Parameters:

  • Resource (OResource)

    to release

  • Authorization (Authorizer)

    context



767
768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/omf-sfa/am/am_manager.rb', line 767

def release_resource(resource, authorizer)
  authorizer.can_release_resource?(resource)
  @scheduler.release_resource(resource, authorizer)
  #resource.remove_from_all_groups

  # if r.kind_of? OMF::SFA::Resource::CompGroup
  #   # groups don't go back in the pool, they are created per account
  #   r.destroy
  # else
  #   r.account = def_account
  #   r.save
  # end
  #resource.destroy
end

#release_resources(resources, authorizer) ⇒ Object

Release an array of resources.

Parameters:

  • Resources (Array<OResource>)

    to release

  • Authorization (Authorizer)

    context



754
755
756
757
758
# File 'lib/omf-sfa/am/am_manager.rb', line 754

def release_resources(resources, authorizer)
  resources.each do |r|
    release_resource(r, authorizer)
  end
end

#renew_account_until(account_descr, expiration_time, authorizer) ⇒ OAccount

Renew account described by account_descr hash until expiration_time. ALready closed or expired accounts can’t be renewed.

Parameters:

  • properties (Hash)

    of account

  • time (Time)

    until account should remain valid

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



155
156
157
158
159
160
161
# File 'lib/omf-sfa/am/am_manager.rb', line 155

def (, expiration_time, authorizer)
   = (, authorizer)
  authorizer.can_renew_account?(, expiration_time)
  .valid_until = expiration_time
  .save
  
end

#update_lease_from_rspec(lease_el, authorizer) ⇒ OLease

Create or Modify leases through RSpecs

When a uuid is provided, then the corresponding lease is modified. Otherwise a new lease is created with the properties described in the RSpecs.

Parameters:

  • RSpec (Nokogiri::XML::Node)

    fragment describing lease and its properties

  • Defines (Authorizer)

    context for authorization decisions

Returns:

  • (OLease)

    The requested lease

Raises:



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/omf-sfa/am/am_manager.rb', line 350

def update_lease_from_rspec(lease_el, authorizer)

  lease_properties = {:valid_from => Time.parse(lease_el[:valid_from]), :valid_until => Time.parse(lease_el[:valid_until])}

  begin
    raise UnavailableResourceException unless UUID.validate(lease_el[:id])
    lease = find_lease({:uuid => lease_el[:id]}, {}, authorizer)
    if lease.valid_from != lease_properties[:valid_from] || lease.valid_until != lease_properties[:valid_until]
      lease = modify_lease(lease_properties, lease, authorizer)
      return { lease_el[:id] => lease }
    else
      return { lease_el[:id] => lease }
    end
  rescue UnavailableResourceException
    lease_descr = {:name => authorizer..name}
    lease = find_or_create_lease(lease_descr, lease_properties, authorizer)
    return { lease_el[:id] => lease }
  end

  #unless lease_el[:uuid].nil?
  #  lease = find_lease({:uuid => lease_el[:uuid]}, {}, authorizer)
  #  raise UnavailableResourceException.new "Unknown lease uuid'#{lease_el[:uuid]}'" unless lease
  #  if lease.valid_from != lease_properties[:valid_from] || lease.valid_until != lease_properties[:valid_until]
  #    lease = modify_lease(lease_properties, lease, authorizer)
  #    { lease_el[:leaseID] => lease }
  #  else
  #    { lease_el[:leaseID] => lease }
  #  end
  #else
  #  lease_descr = {:name => authorizer.account.name}
  #  lease = find_or_create_lease(lease_descr, lease_properties, authorizer)
  #  { lease_el[:leaseID] => lease }
  #end
end

#update_leases_from_rspec(leases, authorizer) ⇒ Hash{String => OLease}

Update the leases described in leases. Any lease not already assigned to the requesting account will be added. If clean_state is true, the state of all described leases is set to the state described with all other properties set to their default values. Any leases not mentioned are canceled. Returns the list of leases requested or throw an error if ANY of the requested leases isn’t available.

Parameters:

  • RSpec (Element)

    fragment describing leases and their properties

  • Defines (Authorizer)

    context for authorization decisions

Returns:

  • (Hash{String => OLease})

    The leases requested

Raises:



397
398
399
400
401
402
403
404
405
406
407
# File 'lib/omf-sfa/am/am_manager.rb', line 397

def update_leases_from_rspec(leases, authorizer)
  debug "update_leases_from_rspec: leases:'#{leases.inspect}' authorizer:'#{authorizer.inspect}'"
  leases_hash = {}
  unless leases.empty?
    leases.each do |lease|
        l = update_lease_from_rspec(lease, authorizer)
        leases_hash.merge!(l)
    end
  end
  leases_hash
end

#update_resource_from_rspec(resource_el, leases, clean_state, authorizer) ⇒ Object

Update a single resource described in resource_el. The respective account is extracted from opts. Any mentioned resources not already available to the requesting account will be created. If clean_state is set to true, all state of a resource not specifically described will be reset to it’s default value. Returns the resource updated.



689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
# File 'lib/omf-sfa/am/am_manager.rb', line 689

def update_resource_from_rspec(resource_el, leases, clean_state, authorizer)
  if uuid_attr = (resource_el.attributes['uuid'] || resource_el.attributes['idref'])
    uuid = UUIDTools::UUID.parse(uuid_attr.value)
    resource = find_resource({:uuid => uuid}, authorizer) # wouldn't know what to create
  elsif comp_id_attr = resource_el.attributes['component_id']
    comp_id = comp_id_attr.value
    comp_gurn = OMF::SFA::Resource::GURN.parse(comp_id)
    #if uuid = comp_gurn.uuid
    #  resource_descr = {:uuid => uuid}
    #else
    #  resource_descr = {:name => comp_gurn.short_name}
    #end
    resource_descr = {:urn => comp_gurn}
    resource = (resource_descr, comp_gurn.type, {}, authorizer)
    unless resource
      raise UnknownResourceException.new "Resource '#{resource_el.to_s}' is not available or doesn't exist"
    end
  elsif name_attr = resource_el.attributes['component_name']
    # the only resource we can find by a name attribute is a group
    # TODO: Not sure about the 'group' assumption
    name = name_attr.value
    resource = ({:name => name}, 'unknown', {}, authorizer)
  else
    raise FormatException.new "Unknown resource description '#{resource_el.attributes.inspect}"
  end

  leases_el = resource_el.xpath('child::ol:lease_ref', 'ol' => OL_NAMESPACE)
  leases_el.each do |lease_el|
    #TODO: provide the scheduler with the resource and the lease to attach them according to its policy.
    # if the scheduler refuses to attach the lease to the resource, we should release both of them.
    lease_id = lease_el['id_ref']
    lease = leases[lease_id]
    @scheduler.lease_component(lease, resource)
  end

  if resource.group?
    members = resource_el.children.collect do |el|
      if el.kind_of?(Nokogiri::XML::Element)
        # ignore any text elements
        update_resource_from_rspec(el, clean_state, authorizer)
      end
    end.compact
    debug "update_resource_from_rspec: Creating members '#{members}' for group '#{resource}'"

    if clean_state
      resource.members = members
    else
      resource.add_members(members)
    end
  else
    if clean_state
      # Set state to what's described in +resource_el+ ONLY
      resource.create_from_xml(resource_el, authorizer)
    else
      resource.update_from_xml(resource_el, authorizer)
    end
  end
  resource.save
  resource
end

#update_resources_from_rspec(descr_el, clean_state, authorizer) ⇒ OResource

Note:

Throws exception if a contained resource doesn’t exist, but will not roll back any

Update the resources described in resource_el. Any resource not already assigned to the requesting account will be added. If clean_state is true, the state of all described resources is set to the state described with all other properties set to their default values. Any resources not mentioned are released. Returns the list of resources requested or throw an error if ANY of the requested resources isn’t available.

Find or create a resource. If it doesn’t exist, is already assigned to someone else, or cannot be created, throws UnknownResourceException.

already performed modifications performed on other resources.

Parameters:

  • RSpec (Element)

    fragment describing resource and their properties

  • Set (Boolean)

    all properties not mentioned to their defaults

  • Defines (Authorizer)

    context for authorization decisions

Returns:

Raises:



609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
# File 'lib/omf-sfa/am/am_manager.rb', line 609

def update_resources_from_rspec(descr_el, clean_state, authorizer)
  debug "update_resources_from_rspec: descr_el:'#{descr_el}' clean_state:'#{clean_state}' authorizer:'#{authorizer}'"
  if !descr_el.nil? && descr_el.name.downcase == 'rspec'
    xsd_path = File.join(File.dirname(__FILE__), '../../../schema/rspec-v3', 'request.xsd')
    schema = Nokogiri::XML::Schema(File.open(xsd_path))

    res = schema.validate(descr_el.document)
    raise FormatException.new("RSpec format is not valid: '#{res}'") unless res.empty?

    unless descr_el.xpath('//ol:*', 'ol' => OL_NAMESPACE).empty?
      #TODO: make proper schemas and validate them
      #lease_xsd_path = File.join(File.dirname(__FILE__), '../../../schema/rspec-v3', 'request-reservation.xsd')
      #lease_rng_path = File.join(File.dirname(__FILE__), '../../../schema/rspec-v3', 'request-reservation.rng')
      #lease_schema = Nokogiri::XML::Schema(File.open(lease_xsd_path))
      #lease_schema = Nokogiri::XML::RelaxNG(File.open(lease_rng_path))

      #res = lease_schema.validate(descr_el.document)
      #raise FormatException.new("RSpec format is not valid: '#{res}'") unless res.empty?
    end


    if descr_el.namespaces.values.include?(OL_NAMESPACE)
      #leases = descr_el.xpath('/rspec//ol:lease', 'ol' => OL_NAMESPACE)
      leases = descr_el.xpath('/xmlns:rspec/ol:lease', 'ol' => OL_NAMESPACE, 'xmlns' => "http://www.geni.net/resources/rspec/3")
      leases = update_leases_from_rspec(leases, authorizer)
    end


    resources = descr_el.xpath('//xmlns:node').collect do |el|
      #debug "create_resources_from_xml::EL: #{el.inspect}"
      if el.kind_of?(Nokogiri::XML::Element)
        # ignore any text elements
        #if el[:lease_name].nil?
        #  update_resource_from_rspec(el, nil, clean_state, authorizer)
        #else # This node has a lease
        #  lease = leases.find { |l| l[:name].eql?(el[:lease_name]) }
        #leases = el.xpath('child::ol:lease', 'ol' => OL_NAMESPACE)
        #leases = update_leases_from_rspec(leases, authorizer)
        update_resource_from_rspec(el, leases, clean_state, authorizer)
        #end
      end
    end.compact

    # channel reservation
    #resources = descr_el.xpath('/xmlns:rspec/ol:channel', 'ol' => OL_NAMESPACE, 'xmlns' => "http://www.geni.net/resources/rspec/3").collect do |el|
    #    update_resource_from_rspec(el, leases, clean_state, authorizer)
    #end.compact

    # TODO: release the unused leases. The leases we have created but we never managed
    # to attach them to a resource because the scheduler denied it.
    if clean_state
      # Now free any leases owned by this account but not contained in +leases+
      all_leases = Set.new
      #leases = descr_el.xpath('//ol:lease', 'ol' => OL_NAMESPACE).collect do |l|
      #  update_leases_from_rspec(leases, authorizer)
      #end.compact

      leases.each {|l| l.all_resources(all_leases)}
      unused = (authorizer., authorizer).to_set - all_leases
      unused.each do |u|
        release_lease(u, authorizer)
      end
      # Now free any resources owned by this account but not contained in +resources+
      rspec_resources = Set.new
      resources.each {|r| r.all_resources(rspec_resources)}
      all_components = (authorizer., authorizer)
      unused = all_components.to_set - rspec_resources
      release_resources(unused, authorizer)
    end
    return resources
  else
    raise FormatException.new "Unknown resources description root '#{descr_el}'"
  end
end