merging with geni-api branch
[sfa.git] / sfa / plc / slices.py
index 18c7584..3625bf0 100644 (file)
@@ -11,31 +11,21 @@ from sfa.util.namespace import *
 from sfa.util.rspec import *
 from sfa.util.specdict import *
 from sfa.util.faults import *
 from sfa.util.rspec import *
 from sfa.util.specdict import *
 from sfa.util.faults import *
-from sfa.util.storage import *
 from sfa.util.record import SfaRecord
 from sfa.util.policy import Policy
 from sfa.util.prefixTree import prefixTree
 from sfa.util.debug import log
 from sfa.util.record import SfaRecord
 from sfa.util.policy import Policy
 from sfa.util.prefixTree import prefixTree
 from sfa.util.debug import log
-from sfa.server.aggregate import Aggregates
-from sfa.server.registry import Registries
 
 MAXINT =  2L**31-1
 
 
 MAXINT =  2L**31-1
 
-class Slices(SimpleStorage):
+class Slices:
 
     rspec_to_slice_tag = {'max_rate':'net_max_rate'}
 
     def __init__(self, api, ttl = .5, origin_hrn=None):
         self.api = api
 
     rspec_to_slice_tag = {'max_rate':'net_max_rate'}
 
     def __init__(self, api, ttl = .5, origin_hrn=None):
         self.api = api
-        self.ttl = ttl
-        self.threshold = None
-        path = self.api.config.SFA_DATA_DIR
-        filename = ".".join([self.api.interface, self.api.hrn, "slices"])
-        filepath = path + os.sep + filename
-        self.slices_file = filepath
-        SimpleStorage.__init__(self, self.slices_file)
+        #filepath = path + os.sep + filename
         self.policy = Policy(self.api)    
         self.policy = Policy(self.api)    
-        self.load()
         self.origin_hrn = origin_hrn
 
     def get_slivers(self, xrn, node=None):
         self.origin_hrn = origin_hrn
 
     def get_slivers(self, xrn, node=None):
@@ -178,120 +168,62 @@ class Slices(SimpleStorage):
 
         return sfa_peer 
 
 
         return sfa_peer 
 
-    def refresh(self):
-        """
-        Update the cached list of slices
-        """
-        # Reload components list
-        now = datetime.datetime.now()
-        if not self.has_key('threshold') or not self.has_key('timestamp') or \
-           now > datetime.datetime.fromtimestamp(time.mktime(time.strptime(self['threshold'], self.api.time_format))):
-            if self.api.interface in ['aggregate']:
-                self.refresh_slices_aggregate()
-            elif self.api.interface in ['slicemgr']:
-                self.refresh_slices_smgr()
-
-    def refresh_slices_aggregate(self):
-        slices = self.api.plshell.GetSlices(self.api.plauth, {'peer_id': None}, ['name'])
-        slice_hrns = [slicename_to_hrn(self.api.hrn, slice['name']) for slice in slices]
-
-         # update timestamp and threshold
-        timestamp = datetime.datetime.now()
-        hr_timestamp = timestamp.strftime(self.api.time_format)
-        delta = datetime.timedelta(hours=self.ttl)
-        threshold = timestamp + delta
-        hr_threshold = threshold.strftime(self.api.time_format)
-        
-        slice_details = {'hrn': slice_hrns,
-                         'timestamp': hr_timestamp,
-                         'threshold': hr_threshold
-                        }
-        self.update(slice_details)
-        self.write()     
-        
-
-    def refresh_slices_smgr(self):
-        slice_hrns = []
-        aggregates = Aggregates(self.api)
-        credential = self.api.getCredential()
-        for aggregate in aggregates:
-            success = False
-            # request hash is optional so lets try the call without it 
-            try:
-                slices = aggregates[aggregate].get_slices(credential)
-                slice_hrns.extend(slices)
-                success = True
-            except:
-                print >> log, "%s" % (traceback.format_exc())
-                print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
-
-            # try sending the request hash if the previous call failed 
-            if not success:
-                arg_list = [credential]
-                try:
-                    slices = aggregates[aggregate].get_slices(credential)
-                    slice_hrns.extend(slices)
-                    success = True
-                except:
-                    print >> log, "%s" % (traceback.format_exc())
-                    print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
-
-        # update timestamp and threshold
-        timestamp = datetime.datetime.now()
-        hr_timestamp = timestamp.strftime(self.api.time_format)
-        delta = datetime.timedelta(hours=self.ttl)
-        threshold = timestamp + delta
-        hr_threshold = threshold.strftime(self.api.time_format)
-
-        slice_details = {'hrn': slice_hrns,
-                         'timestamp': hr_timestamp,
-                         'threshold': hr_threshold
-                        }
-        self.update(slice_details)
-        self.write()
-
-
-    def verify_site(self, registry, credential, slice_hrn, peer, sfa_peer):
+    def verify_site(self, registry, credential, slice_hrn, peer, sfa_peer, reg_objects=None):
         authority = get_authority(slice_hrn)
         authority_urn = hrn_to_urn(authority, 'authority')
         authority = get_authority(slice_hrn)
         authority_urn = hrn_to_urn(authority, 'authority')
-        site_records = registry.resolve(credential, authority_urn)
+        
+        if reg_objects:
+            site = reg_objects['site']
+        else:
+            site_records = registry.resolve(credential, authority_urn)
+            site = {}            
+            for site_record in site_records:            
+                if site_record['type'] == 'authority':
+                    site = site_record
+            if not site:
+                raise RecordNotFound(authority)
             
             
-        site = {}
-        for site_record in site_records:
-            if site_record['type'] == 'authority':
-                site = site_record
-        if not site:
-            raise RecordNotFound(authority)
         remote_site_id = site.pop('site_id')    
                 
         login_base = get_leaf(authority)
         sites = self.api.plshell.GetSites(self.api.plauth, login_base)
         remote_site_id = site.pop('site_id')    
                 
         login_base = get_leaf(authority)
         sites = self.api.plshell.GetSites(self.api.plauth, login_base)
+
         if not sites:
             site_id = self.api.plshell.AddSite(self.api.plauth, site)
             if peer:
                 self.api.plshell.BindObjectToPeer(self.api.plauth, 'site', site_id, peer, remote_site_id)   
             # mark this site as an sfa peer record
         if not sites:
             site_id = self.api.plshell.AddSite(self.api.plauth, site)
             if peer:
                 self.api.plshell.BindObjectToPeer(self.api.plauth, 'site', site_id, peer, remote_site_id)   
             # mark this site as an sfa peer record
-            if sfa_peer:
+            if sfa_peer and not reg_objects:
                 peer_dict = {'type': 'authority', 'hrn': authority, 'peer_authority': sfa_peer, 'pointer': site_id}
                 registry.register_peer_object(credential, peer_dict)
         else:
             site_id = sites[0]['site_id']
             remote_site_id = sites[0]['peer_site_id']
                 peer_dict = {'type': 'authority', 'hrn': authority, 'peer_authority': sfa_peer, 'pointer': site_id}
                 registry.register_peer_object(credential, peer_dict)
         else:
             site_id = sites[0]['site_id']
             remote_site_id = sites[0]['peer_site_id']
+            
+           old_site = sites[0]
+           #the site is already on the remote agg. Let us update(e.g. max_slices field) it with the latest info.
+            self.sync_site(old_site, site, peer)
 
 
         return (site_id, remote_site_id) 
 
 
 
         return (site_id, remote_site_id) 
 
-    def verify_slice(self, registry, credential, slice_hrn, site_id, remote_site_id, peer, sfa_peer):
+    def verify_slice(self, registry, credential, slice_hrn, site_id, remote_site_id, peer, sfa_peer, reg_objects=None):
         slice = {}
         slice_record = None
         authority = get_authority(slice_hrn)
         slice = {}
         slice_record = None
         authority = get_authority(slice_hrn)
-        slice_records = registry.resolve(credential, slice_hrn)
 
 
-        for record in slice_records:
-            if record['type'] in ['slice']:
-                slice_record = record
-        if not slice_record:
-            raise RecordNotFound(hrn)
+        if reg_objects:
+            slice_record = reg_objects['slice_record']
+        else:
+            slice_records = registry.resolve(credential, slice_hrn)
+    
+            for record in slice_records:
+                if record['type'] in ['slice']:
+                    slice_record = record
+            if not slice_record:
+                raise RecordNotFound(hrn)
+            
+        
         slicename = hrn_to_pl_slicename(slice_hrn)
         parts = slicename.split("_")
         login_base = parts[0]
         slicename = hrn_to_pl_slicename(slice_hrn)
         parts = slicename.split("_")
         login_base = parts[0]
@@ -325,33 +257,39 @@ class Slices(SimpleStorage):
            self.sync_slice(slice, slice_record, peer)
 
         slice['peer_slice_id'] = slice_record['pointer']
            self.sync_slice(slice, slice_record, peer)
 
         slice['peer_slice_id'] = slice_record['pointer']
-        self.verify_persons(registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer)
+        self.verify_persons(registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer, reg_objects)
     
         return slice        
 
     
         return slice        
 
-    def verify_persons(self, registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer):
+    def verify_persons(self, registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer, reg_objects=None):
         # get the list of valid slice users from the registry and make 
         # sure they are added to the slice 
         slicename = hrn_to_pl_slicename(slice_record['hrn'])
         # get the list of valid slice users from the registry and make 
         # sure they are added to the slice 
         slicename = hrn_to_pl_slicename(slice_record['hrn'])
-        researchers = slice_record.get('researcher', [])
+        if reg_objects:
+            researchers = reg_objects['users'].keys()
+        else:
+            researchers = slice_record.get('researcher', [])
         for researcher in researchers:
         for researcher in researchers:
-            person_record = {}
-            person_records = registry.resolve(credential, researcher)
-            for record in person_records:
-                if record['type'] in ['user']:
-                    person_record = record
-            if not person_record:
-                pass
-            person_dict = person_record
+            if reg_objects:
+                person_dict = reg_objects['users'][researcher]
+            else:
+                person_records = registry.resolve(credential, researcher)
+                for record in person_records:
+                    if record['type'] in ['user'] and record['enabled']:
+                        person_record = record
+                if not person_record:
+                    return 1
+                person_dict = person_record
+
             local_person=False
             if peer:
                 peer_id = self.api.plshell.GetPeers(self.api.plauth, {'shortname': peer}, ['peer_id'])[0]['peer_id']
                 persons = self.api.plshell.GetPersons(self.api.plauth, {'email': [person_dict['email']], 'peer_id': peer_id}, ['person_id', 'key_ids'])
             local_person=False
             if peer:
                 peer_id = self.api.plshell.GetPeers(self.api.plauth, {'shortname': peer}, ['peer_id'])[0]['peer_id']
                 persons = self.api.plshell.GetPersons(self.api.plauth, {'email': [person_dict['email']], 'peer_id': peer_id}, ['person_id', 'key_ids'])
-               if not persons:
-                   persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])
-                   if persons:
-                       local_person=True
-
+                if not persons:
+                    persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])
+                    if persons:
+                        local_person=True
+                        
             else:
                 persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])   
         
             else:
                 persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])   
         
@@ -417,8 +355,7 @@ class Slices(SimpleStorage):
         slicename = hrn_to_pl_slicename(hrn) 
         slice = {}
         slice_record = None
         slicename = hrn_to_pl_slicename(hrn) 
         slice = {}
         slice_record = None
-        registries = Registries(self.api)
-        registry = registries[self.api.hrn]
+        registry = self.api.registries[self.api.hrn]
         credential = self.api.getCredential()
 
         site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
         credential = self.api.getCredential()
 
         site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
@@ -484,11 +421,23 @@ class Slices(SimpleStorage):
 
         return 1
 
 
         return 1
 
+    def sync_site(self, old_record, new_record, peer):
+        if old_record['max_slices'] != new_record['max_slices'] or old_record['max_slivers'] != new_record['max_slivers']:
+            if peer:
+                self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'site', old_record['site_id'], peer)
+           if old_record['max_slices'] != new_record['max_slices']:
+                self.api.plshell.UpdateSite(self.api.plauth, old_record['site_id'], {'max_slices' : new_record['max_slices']})
+           if old_record['max_slivers'] != new_record['max_slivers']:
+               self.api.plshell.UpdateSite(self.api.plauth, old_record['site_id'], {'max_slivers' : new_record['max_slivers']})
+           if peer:
+                self.api.plshell.BindObjectToPeer(self.api.plauth, 'site', old_record['site_id'], peer, old_record['peer_site_id'])
+       return 1
+
     def sync_slice(self, old_record, new_record, peer):
         if old_record['expires'] != new_record['expires']:
             if peer:
                 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'slice', old_record['slice_id'], peer)
     def sync_slice(self, old_record, new_record, peer):
         if old_record['expires'] != new_record['expires']:
             if peer:
                 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'slice', old_record['slice_id'], peer)
-                self.api.plshell.UpdateSlice(self.api.plauth, old_record['slice_id'], {'expires' : new_record['expires']})
+            self.api.plshell.UpdateSlice(self.api.plauth, old_record['slice_id'], {'expires' : new_record['expires']})
            if peer:
                 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', old_record['slice_id'], peer, old_record['peer_slice_id'])
        return 1
            if peer:
                 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', old_record['slice_id'], peer, old_record['peer_slice_id'])
        return 1