From 108f6d000af6517d3b22501255b377a83568b946 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Wed, 18 Jan 2012 13:09:10 +0100 Subject: [PATCH] various tweaks around using records; the client-side is still broken --- sfa/client/sfi.py | 47 +++++++++++++++++++------------ sfa/managers/registry_manager.py | 6 ++-- sfa/methods/GetSelfCredential.py | 3 +- sfa/server/sfa-start.py | 11 ++++---- sfa/storage/persistentobjs.py | 48 +++++++++++++++++++++++++++----- tests/testStorage.py | 2 +- 6 files changed, 79 insertions(+), 38 deletions(-) diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 4ff43acb..6f2d5b71 100644 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -28,7 +28,8 @@ from sfa.util.config import Config from sfa.util.version import version_core from sfa.util.cache import Cache -from sfa.storage.record import SfaRecord, UserRecord, SliceRecord, NodeRecord, AuthorityRecord +#from sfa.storage.record import SfaRecord, UserRecord, SliceRecord, NodeRecord, AuthorityRecord +from sfa.storage.persistentobjs import RegRecord from sfa.rspecs.rspec import RSpec from sfa.rspecs.rspec_converter import RSpecConverter @@ -119,15 +120,15 @@ def save_records_to_file(filename, recordList, format="xml"): f = open(filename, "w") f.write("\n") for record in recordList: - record = SfaRecord(dict=record) - f.write('\n') + record_obj=RegRecord (dict=record) + f.write('\n') f.write("\n") f.close() elif format == "hrnlist": f = open(filename, "w") for record in recordList: - record = SfaRecord(dict=record) - f.write(record.get_name() + "\n") + record_obj=RegRecord (dict=record) + f.write(record.hrn + "\n") f.close() else: # this should never happen @@ -135,15 +136,19 @@ def save_records_to_file(filename, recordList, format="xml"): def save_record_to_file(filename, record): if record['type'] in ['user']: - record = UserRecord(dict=record) + # UserRecord + record = RegRecord(dict=record) elif record['type'] in ['slice']: - record = SliceRecord(dict=record) + # SliceRecord + record = RegRecord(dict=record) elif record['type'] in ['node']: - record = NodeRecord(dict=record) + # NodeRecord + record = RegRecord(dict=record) elif record['type'] in ['authority', 'ma', 'sa']: - record = AuthorityRecord(dict=record) + # AuthorityRecord + record = RegRecord(dict=record) else: - record = SfaRecord(dict=record) + record = RegRecord(dict=record) str = record.save_to_string() f=codecs.open(filename, encoding='utf-8',mode="w") f.write(str) @@ -156,7 +161,8 @@ def load_record_from_file(filename): f=codecs.open(filename, encoding="utf-8", mode="r") str = f.read() f.close() - record = SfaRecord(string=str) + record = RegRecord() + record.load_from_xml(str) return record @@ -714,19 +720,24 @@ or version information about sfi itself self.logger.error("No record of type %s"% options.type) for record in records: if record['type'] in ['user']: - record = UserRecord(dict=record) + # UserRecord + record = RegRecord(dict=record) elif record['type'] in ['slice']: - record = SliceRecord(dict=record) + # SliceRecord + record = RegRecord(dict=record) elif record['type'] in ['node']: - record = NodeRecord(dict=record) + # NodeRecord + record = RegRecord(dict=record) elif record['type'].startswith('authority'): - record = AuthorityRecord(dict=record) + # AuthorityRecord + record = RegRecord(dict=record) else: - record = SfaRecord(dict=record) + record = RegRecord(dict=record) + if (options.format == "text"): record.dump() else: - print record.save_to_string() + print record.save_as_xml() if options.file: save_records_to_file(options.file, records, options.fileformat) return @@ -739,7 +750,7 @@ or version information about sfi itself sys.exit(1) record_filepath = args[0] rec_file = self.get_record_file(record_filepath) - record = load_record_from_file(rec_file).as_dict() + record = load_record_from_file(rec_file).todict() return self.registry().Register(record, auth_cred) def update(self, options, args): diff --git a/sfa/managers/registry_manager.py b/sfa/managers/registry_manager.py index 8ce7705d..ef00d9cb 100644 --- a/sfa/managers/registry_manager.py +++ b/sfa/managers/registry_manager.py @@ -261,8 +261,7 @@ class RegistryManager: raise ExistingRecord(hrn) assert ('type' in record_dict) - record = RegRecord("undefined") - record.set_from_dict(record_dict) + record = RegRecord(dict=record_dict) record.just_created() record.authority = get_authority(record.hrn) auth_info = api.auth.get_auth_info(record.authority) @@ -305,8 +304,7 @@ class RegistryManager: def Update(self, api, record_dict): assert ('type' in record_dict) - new_record=RegRecord(type="unknown") - new_record.set_from_dict(record_dict) + new_record=RegRecord(dict=record_dict) type = new_record.type hrn = new_record.hrn diff --git a/sfa/methods/GetSelfCredential.py b/sfa/methods/GetSelfCredential.py index b8eb18a3..40220089 100644 --- a/sfa/methods/GetSelfCredential.py +++ b/sfa/methods/GetSelfCredential.py @@ -67,8 +67,7 @@ class GetSelfCredential(Method): if not records: raise RecordNotFound(hrn) - record_obj = RegRecord ('unknown') - record_obj.set_from_dict (records[0]) + record_obj = RegRecord (dict=records[0]) # xxx-local the local-only version would read #record_obj = dbsession.query(RegRecord).filter_by(hrn=hrn).first() #if not record_obj: raise RecordNotFound(hrn) diff --git a/sfa/server/sfa-start.py b/sfa/server/sfa-start.py index fe811ff9..1f222155 100755 --- a/sfa/server/sfa-start.py +++ b/sfa/server/sfa-start.py @@ -151,12 +151,11 @@ def update_cert_records(gids): hrn, type = gid.get_hrn(), gid.get_type() record = dbsession.query(RegRecord).filter_by(hrn=hrn, type=type,pointer=-1).first() if not record: - record = RegRecord (type=type) - record.set_from_dict ( - { 'hrn': hrn, - 'authority': get_authority(hrn), - 'gid': gid.save_to_string(save_parents=True), - }) + record = RegRecord (dict= {'type':type, + 'hrn': hrn, + 'authority': get_authority(hrn), + 'gid': gid.save_to_string(save_parents=True), + }) dbsession.add(record) dbsession.commit() diff --git a/sfa/storage/persistentobjs.py b/sfa/storage/persistentobjs.py index a1f4cb60..db626087 100644 --- a/sfa/storage/persistentobjs.py +++ b/sfa/storage/persistentobjs.py @@ -9,6 +9,7 @@ from sqlalchemy.orm import object_mapper from sqlalchemy.ext.declarative import declarative_base from sfa.util.sfalogging import logger +from sfa.util.xml import XML from sfa.trust.gid import GID @@ -41,7 +42,7 @@ Base=declarative_base() # so the latter obj.todict() seems more reliable but more hacky as is relies on the form of fields, so this can probably be improved # # (*) finally for converting a dictionary into an sqlalchemy object, we provide -# obj.set_from_dict(dict) +# obj.load_from_dict(dict) class AlchemyObj: def __iter__(self): @@ -54,13 +55,35 @@ class AlchemyObj: d=self.__dict__ keys=[k for k in d.keys() if not k.startswith('_')] return dict ( [ (k,d[k]) for k in keys ] ) - def set_from_dict (self, d): + def load_from_dict (self, d): for (k,v) in d.iteritems(): # experimental if isinstance(v, StringTypes): if v.lower() in ['true']: v=True if v.lower() in ['false']: v=False setattr(self,k,v) + assert self.type in BUILTIN_TYPES + + # in addition we provide convenience for converting to and from xml records + # for this purpose only, we need the subclasses to define 'fields' as either + # a list or a dictionary + def xml_fields (self): + fields=self.fields + if isinstance(fields,dict): fields=fields.keys() + return fields + def load_from_xml (self, xml): + xml_record = XML(xml) + xml_dict = xml_record.todict() + for k in self.xml_fields(): + if k in xml_dict: + setattr(self,k,xml_dict[k]) + + def save_as_xml (self): + # xxx unset fields don't get exposed, is that right ? + input_dict = dict( [ (key, getattr(self.key), ) for key in self.xml_fields() if getattr(self,key,None) ] ) + xml_record=XML("") + xml_record.parse_dict (input_dict) + return xml_record.toxml() ############################## class Type (Base): @@ -96,7 +119,9 @@ class RegRecord (Base,AlchemyObj): Column ('date_created',DateTime), Column ('last_updated',DateTime), ) - def __init__ (self, type, hrn=None, gid=None, authority=None, peer_authority=None, pointer=-1): + fields = [ 'type', 'hrn', 'gid', 'authority', 'peer_authority' ] + def __init__ (self, type='unknown', hrn=None, gid=None, authority=None, peer_authority=None, + pointer=-1, dict=None): self.type=type if hrn: self.hrn=hrn if gid: @@ -104,7 +129,9 @@ class RegRecord (Base,AlchemyObj): else: self.gid=gid.save_to_string(save_parents=True) if authority: self.authority=authority if peer_authority: self.peer_authority=peer_authority - self.pointer=pointer + if not hasattr(self,'pointer'): self.pointer=pointer + if dict: + self.load_from_dict (dict) def __repr__(self): result="[Record(record_id=%s, hrn=%s, type=%s, authority=%s, pointer=%s" % \ @@ -114,6 +141,7 @@ class RegRecord (Base,AlchemyObj): result += "]" return result + # xxx - there might be smarter ways to handle get/set'ing gid using validation hooks def get_gid_object (self): if not self.gid: return None else: return GID(string=self.gid) @@ -152,14 +180,20 @@ class UserRecord (Base): self.email=email def __repr__ (self): return ""%(self.email,self.gid) -############################## +############################## def init_tables(dbsession): logger.info("Initializing db schema and builtin types") - engine=dbsession.get_bind() + # the doc states we could retrieve the engine this way + # engine=dbsession.get_bind() + # however I'm getting this + # TypeError: get_bind() takes at least 2 arguments (1 given) + # so let's import alchemy - but not from toplevel + from sfa.storage.alchemy import engine Base.metadata.create_all(engine) insert_builtin_types(dbsession) def drop_tables(dbsession): logger.info("Dropping tables") - engine=dbsession.get_bind() + # same as for init_tables + from sfa.storage.alchemy import engine Base.metadata.drop_all(engine) diff --git a/tests/testStorage.py b/tests/testStorage.py index deb69f4e..1790b73d 100755 --- a/tests/testStorage.py +++ b/tests/testStorage.py @@ -8,7 +8,7 @@ class TestStorage(unittest.TestCase): pass def testCreate(self): - r = RegRecord('user') + r = RegRecord(type='authority',hrn='foo.bar') if __name__ == "__main__": unittest.main() -- 2.43.0