huge cleanup for removing mutables used as default
[sfa.git] / sfa / managers / registry_manager.py
index b49507a..5a49d47 100644 (file)
@@ -12,6 +12,8 @@ from sfa.util.xrn import Xrn, get_authority, hrn_to_urn, urn_to_hrn
 from sfa.util.version import version_core
 from sfa.util.sfalogging import logger
 
+from sfa.util.printable import printable
+
 from sfa.trust.gid import GID 
 from sfa.trust.credential import Credential
 from sfa.trust.certificate import Certificate, Keypair, convert_public_key
@@ -23,6 +25,41 @@ from sfa.storage.model import make_record, RegRecord, RegAuthority, RegUser, Reg
 # them on the xmlrpc wire
 from sqlalchemy.orm.collections import InstrumentedList
 
+### historical note -- april 2014
+# the myslice chaps rightfully complained about the following discrepancy
+# they found that
+# * read operations (resolve) expose stuff like e.g. 
+#   'reg-researchers', or 'reg-pis', but that
+# * write operations (register, update) need e.g. 
+#   'researcher' or 'pi' to be set - reg-* are just ignored
+#
+# the 'normalize' helper functions below aim at ironing this out
+# however in order to break as few code as possible we essentially make sure that *both* fields are set
+# upon entering the write methods (so again register and update) for legacy, as some driver code
+# might depend on the presence of, say, 'researcher'
+
+# normalize an input record to a write method - register or update
+# e.g. registry calls this 'reg-researchers'
+# while some drivers call this 'researcher'
+# we need to make sure that both keys appear and are the same
+def _normalize_input (record, reg_key, driver_key):
+    # this looks right, use this for both keys
+    if reg_key in record:
+        # and issue a warning if they were both set and different
+        # as we're overwriting some user data here
+        if driver_key in record:
+            logger.warning ("normalize_input_researcher: incoming record has both values, using reg-researchers")
+        record[driver_key]=record[reg_key]
+    # we only have one key set, duplicate for the other one
+    elif driver_key in record:
+        logger.warning ("normalize_input_researcher: you should use '%s' instead ot '%s'"%(reg_key,driver_key))
+        record[reg_key]=record[driver_key]
+
+def normalize_input_record (record):
+    _normalize_input (record, 'reg-researchers','researcher')
+    _normalize_input (record, 'reg-pis','pi')
+    return record
+
 class RegistryManager:
 
     def __init__ (self, config): 
@@ -32,7 +69,7 @@ class RegistryManager:
     def GetVersion(self, api, options):
         peers = dict ( [ (hrn,interface.get_url()) for (hrn,interface) in api.registries.iteritems() 
                        if hrn != api.hrn])
-        xrn=Xrn(api.hrn)
+        xrn=Xrn(api.hrn,type='authority')
         return version_core({'interface':'registry',
                              'sfa': 2,
                              'geni_api': 2,
@@ -200,7 +237,8 @@ class RegistryManager:
     
         return records
     
-    def List (self, api, xrn, origin_hrn=None, options={}):
+    def List (self, api, xrn, origin_hrn=None, options=None):
+        if options is None: options={}
         dbsession=api.dbsession()
         # load all know registry names into a prefix tree and attempt to find
         # the longest matching prefix
@@ -293,6 +331,10 @@ class RegistryManager:
 
     def Register(self, api, record_dict):
     
+        logger.debug("Register: entering with record_dict=%s"%printable(record_dict))
+        normalize_input_record (record_dict)
+        logger.debug("Register: normalized record_dict=%s"%printable(record_dict))
+
         dbsession=api.dbsession()
         hrn, type = record_dict['hrn'], record_dict['type']
         urn = hrn_to_urn(hrn,type)
@@ -338,11 +380,11 @@ class RegistryManager:
             record.gid=gid.save_to_string(save_parents=True)
 
             # locate objects for relationships
-            pi_hrns = getattr(record,'pi',None)
+            pi_hrns = getattr(record,'reg-pis',None)
             if pi_hrns is not None: record.update_pis (pi_hrns, dbsession)
 
         elif isinstance (record, RegSlice):
-            researcher_hrns = getattr(record,'researcher',None)
+            researcher_hrns = getattr(record,'reg-researchers',None)
             if researcher_hrns is not None: record.update_researchers (researcher_hrns, dbsession)
         
         elif isinstance (record, RegUser):
@@ -364,6 +406,11 @@ class RegistryManager:
         return record.get_gid_object().save_to_string(save_parents=True)
     
     def Update(self, api, record_dict):
+
+        logger.debug("Update: entering with record_dict=%s"%printable(record_dict))
+        normalize_input_record (record_dict)
+        logger.debug("Update: normalized record_dict=%s"%printable(record_dict))
+
         dbsession=api.dbsession()
         assert ('type' in record_dict)
         new_record=make_record(dict=record_dict)
@@ -402,11 +449,11 @@ class RegistryManager:
 
         # update native relations
         if isinstance (record, RegSlice):
-            researcher_hrns = getattr(new_record,'researcher',None)
+            researcher_hrns = getattr(new_record,'reg-researchers',None)
             if researcher_hrns is not None: record.update_researchers (researcher_hrns, dbsession)
 
         elif isinstance (record, RegAuthority):
-            pi_hrns = getattr(new_record,'pi',None)
+            pi_hrns = getattr(new_record,'reg-pis',None)
             if pi_hrns is not None: record.update_pis (pi_hrns, dbsession)
         
         # update the PLC information that was specified with the record