#!/usr/local/bin/python import copy from deter import topdl from datetime import datetime, timedelta from numbers import Number class federated_service: def __init__(self, name, exporter=None, importers=None, params=None, reqs=None, portal=None): self.name=name self.exporter=exporter if importers is None: self.importers = [] else: self.importers=importers if params is None: self.params = { } else: self.params = params if reqs is None: self.reqs = [] else: self.reqs = reqs if portal is not None: self.portal = portal else: self.portal = (name in federated_service.needs_portal) def to_topdl(self): return topdl.Service(name=self.name, importer=self.importers) def __str__(self): return "name %s export %s import %s params %s reqs %s" % \ (self.name, self.exporter, self.importers, self.params, [ (r['name'], r['visibility']) for r in self.reqs] ) needs_portal = ('SMB', 'seer', 'tmcd', 'project_export', 'seer_master') class allocation_info: """ An allocation identified by allocationID. It includes the local name of the testbed on which it was allocated and the uri on which to contact it. In addition, the proofs of access are included. """ def __init__(self, allocID, tb, uri, proof=None, services=None): self.allocID = allocID self.tb = tb self.uri = uri self.proof = proof if services is not None: self.services = services else: self.services = [ ] self.attrs = { } def set_attribute(self, a, v): a = a.lower() if a not in self.attrs: self.attrs[a] = v def get_attribute(self, a, default=None): a = a.lower() return self.attrs.get(a, default) class experiment_info: """ Information about an experiment in the eperiment controller. It includes the fedid and localnames, the identity the experiment acts as, current status, topology allocation logs and the allocations themselves. """ def __init__(self, fedid, localname, identity=None): self.fedid = fedid self.localname = localname self.identity = identity self.top = None self.status = 'empty' self.log = [] self.alloc = { } self.last_update = datetime.now() def add_allocation(self, a): self.alloc[a.tb] = a def get_allocation(self, tb): return self.alloc.get(tb,None) def get_all_allocations(self): return self.alloc.values() def updated(self): self.last_update = datetime.now() def older_than(self, secs=None, dt=None): """ If the last update of this info was more than secs seconds ago, or before dt (a datetime), return True. If both secs and dt or neither is given return False. If the last update time is completelt unknown (which should never happen) return True. """ if self.last_update is None: return True elif dt is None and isinstance(secs, Number): return self.last_update + timedelta(seconds=secs) < datetime.now() elif secs is None and isinstance(dt, datetime): return self.last_update < dt else: return False def get_info(self): """ Return the information as a dict suitable for a soap return value. This is an infoResponseType in fedd_types.xsd. """ # The state may be massaged by the service function that called # get_info (e.g., encoded for XMLRPC transport) so copy structured # fields. rv = { 'experimentID': [ { 'fedid': copy.deepcopy(self.fedid) }, {'localname': self.localname }, ], 'experimentStatus': self.status, } if self.log: rv['allocationLog'] = "".join(self.log) if self.identity is not None: rv['experimentAccess'] = {'X509': copy.deepcopy(self.identity)} if self.top is not None: rv['experimentdescription'] = \ { 'topdldescription': self.top.to_dict() } return rv