From e74265ec6d973c2da8fd470be4331eacc8d09351 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Tue, 29 Apr 2014 18:28:26 +0200 Subject: [PATCH] dealing with reg-researchers vs researcher register and update now expect 'reg-researchers' to be set for legacy if instead we find 'researcher' (sic: singular) then we pretend it was 'reg-researchers' not terribly nice but should work for that one relation, others to follow --- sfa/client/sfi.py | 9 +++--- sfa/managers/registry_manager.py | 52 ++++++++++++++++++++++++++++++-- sfa/util/printable.py | 15 +++++++++ 3 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 sfa/util/printable.py diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 46c18dfc..4f38ddf2 100644 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -31,6 +31,7 @@ from sfa.util.xrn import get_leaf, get_authority, hrn_to_urn, Xrn from sfa.util.config import Config from sfa.util.version import version_core from sfa.util.cache import Cache +from sfa.util.printable import printable from sfa.storage.record import Record @@ -203,8 +204,8 @@ def load_record_from_opts(options): record_dict['keys'] = [pubkey] if hasattr(options, 'slices') and options.slices: record_dict['slices'] = options.slices - if hasattr(options, 'researchers') and options.researchers is not None: - record_dict['researcher'] = options.researchers + if hasattr(options, 'reg_researchers') and options.reg_researchers is not None: + record_dict['reg-researchers'] = options.reg_researchers if hasattr(options, 'email') and options.email: record_dict['email'] = options.email if hasattr(options, 'pis') and options.pis: @@ -421,8 +422,8 @@ class Sfi: default=None) parser.add_option('-s', '--slices', dest='slices', metavar='', help='Set/replace slice xrns', default='', type="str", action='callback', callback=optparse_listvalue_callback) - parser.add_option('-r', '--researchers', dest='researchers', metavar='', - help='Set/replace slice researchers - use -r none to reset', default='', type="str", action='callback', + parser.add_option('-r', '--researchers', dest='reg_researchers', metavar='', + help='Set/replace slice researchers - use -r none to reset', default=None, type="str", action='callback', callback=optparse_listvalue_callback) parser.add_option('-p', '--pis', dest='pis', metavar='', help='Set/replace Principal Investigators/Project Managers', default='', type="str", action='callback', callback=optparse_listvalue_callback) diff --git a/sfa/managers/registry_manager.py b/sfa/managers/registry_manager.py index 0958f5e0..bfff502b 100644 --- a/sfa/managers/registry_manager.py +++ b/sfa/managers/registry_manager.py @@ -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,43 @@ 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 discrepency +# they found that +# * read operations (resolve) expose stuff like e.g. 'reg-researchers', but that +# * write operations (register, update) need e.g. 'researcher' to be set - it ignores 'reg-researchers' +# +# the 'normalize' helper functions below aim at ironing this out +# however in order to break as few as possible we essentially make sure that *both* fields are set +# upon entering the write methods (so again register and update) because some driver code +# might depend on the presence of, say, 'researcher' + +# registry calls this 'reg-researchers' +# some drivers call this 'researcher' +# this is even more confusing as people might use 'researchers' +def normalize_input_researcher (record): + # this aims at detecting a mispelled input + if 'researchers' in record and 'researcher' not in record: + record['researcher']=record['researchers'] + del record['researchers'] + # this looks right, use this for both keys + if 'reg-researchers' in record: + # and issue a warning if they were both set as we're overwriting some user data here + if 'researcher' in record: + logger.warning ("normalize_input_researcher: incoming record has both values, using reg-researchers") + record['researcher']=record['reg-researchers'] + # we only have one key set, duplicate for the other one + elif 'researcher' in record: + logger.warning ("normalize_input_researcher: you should use 'reg-researchers' instead ot 'researcher'") + record['reg-researchers']=record['researcher'] + # if at this point we still have 'researchers' it's going to be ignored and that might be confusing + if 'researchers' in record: + logger.warning ("normalize_input_researcher: incoming record has confusing 'researchers' key - ignored - use 'reg-researchers' instead") + +def normalize_input_record (record): + normalize_input_researcher (record) + return record + class RegistryManager: def __init__ (self, config): @@ -293,6 +332,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) @@ -342,7 +385,7 @@ class RegistryManager: 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 +407,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,7 +450,7 @@ 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): diff --git a/sfa/util/printable.py b/sfa/util/printable.py new file mode 100644 index 00000000..f18c274b --- /dev/null +++ b/sfa/util/printable.py @@ -0,0 +1,15 @@ +# yet another way to display records... +def beginning (foo,size=15): + full="%s"%foo + if len(full)<=size: return full + return full[:size-3]+'...' + +def printable (record_s): + # a list of records : + if isinstance (record_s,list): + return "[" + "\n".join( [ printable(r) for r in record_s ]) + "]" + if isinstance (record_s, dict): + return "{" + " , ".join( [ "%s:%s"%(k,beginning(v)) for k,v in record_s.iteritems() ] ) + "}" + if isinstance (record_s, str): + return record_s + return "unprintable [[%s]]"%record_s -- 2.43.0