From: Thierry Parmentelat Date: Wed, 15 Dec 2010 15:55:29 +0000 (+0100) Subject: merging rspecs avoid duplicated networks X-Git-Tag: sfa-1.0-10~2 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=7885d66062ba670aff8d2c8069c1e57963218492;p=sfa.git merging rspecs avoid duplicated networks slice manager to use the helper function for merging for get_rspecs as well --- diff --git a/sfa/managers/slice_manager_pl.py b/sfa/managers/slice_manager_pl.py index 756800ca..a58bc80e 100644 --- a/sfa/managers/slice_manager_pl.py +++ b/sfa/managers/slice_manager_pl.py @@ -363,7 +363,6 @@ def get_rspec(api, creds, options): return rspec hrn, type = urn_to_hrn(xrn) - rspec = None # get the callers hrn valid_cred = api.auth.checkCredentials(creds, 'listnodes', hrn)[0] @@ -387,31 +386,13 @@ def get_rspec(api, creds, options): #threads.run(server.get_resources, cred, xrn, origin_hrn) results = threads.get_results() - # combine the rspecs into a single rspec - for agg_rspec in results: - try: - tree = etree.parse(StringIO(agg_rspec)) - except etree.XMLSyntaxError: - message = str(agg_rspec) + ": " + str(sys.exc_info()[1]) - raise InvalidRSpec(message) + merged_rspec = merge_rspecs(results) - root = tree.getroot() - if root.get("type") in ["SFA"]: - if rspec == None: - rspec = root - else: - for network in root.iterfind("./network"): - rspec.append(deepcopy(network)) - for request in root.iterfind("./request"): - rspec.append(deepcopy(request)) - - sfa_logger().debug('get_rspec: rspec=%r'%rspec) - rspec = etree.tostring(rspec, xml_declaration=True, pretty_print=True) # cache the result if api.cache and not xrn: - api.cache.add('nodes', rspec) + api.cache.add('nodes', merged_rspec) - return rspec + return merged_rspec def main(): r = RSpec() diff --git a/sfa/util/rspecHelper.py b/sfa/util/rspecHelper.py index a943190a..8174e6bc 100755 --- a/sfa/util/rspecHelper.py +++ b/sfa/util/rspecHelper.py @@ -1,11 +1,14 @@ #! /usr/bin/env python import sys + from copy import deepcopy from lxml import etree from StringIO import StringIO from optparse import OptionParser +from sfa.util.faults import * +from sfa.util.sfalogging import sfa_logger def merge_rspecs(rspecs): """ @@ -15,24 +18,53 @@ def merge_rspecs(rspecs): if not rspecs or not isinstance(rspecs, list): return rspecs + # ugly hack to avoid sending the same info twice, when the call graph has dags + known_networks={} + def register_network (network): + try: + known_networks[network.get('name')]=True + except: + sfa_logger().error("merge_rspecs: cannot register network with no name in rspec") + pass + def is_registered_network (network): + try: + return network.get('name') in known_networks + except: + sfa_logger().error("merge_rspecs: cannot retrieve network with no name in rspec") + return False + + # the resulting tree rspec = None - for tmp_rspec in rspecs: + for input_rspec in rspecs: try: - tree = etree.parse(StringIO(tmp_rspec)) + tree = etree.parse(StringIO(input_rspec)) except etree.XMLSyntaxError: # consider failing silently here - message = str(agg_rspec) + ": " + str(sys.exc_info()[1]) + sfa_logger().log_exc("merge_rspecs, parse error") + message = str(sys.exc_info()[1]) + ' with ' + input_rspec raise InvalidRSpec(message) root = tree.getroot() - if root.get("type") in ["SFA"]: - if rspec == None: - rspec = root - else: - for network in root.iterfind("./network"): + if not root.get("type") in ["SFA"]: + sfa_logger().error("merge_rspecs: unexpected type for rspec root, %s"%root.get('type')) + continue + if rspec == None: + # we scan the first input, register all networks + # in addition we remove duplicates - needed until everyone runs 1.0-10 + rspec = root + for network in root.iterfind("./network"): + if not is_registered_network(network): + register_network(network) + else: + # duplicate in the first input - trash it + root.remove(network) + else: + for network in root.iterfind("./network"): + if not is_registered_network(network): rspec.append(deepcopy(network)) - for request in root.iterfind("./request"): - rspec.append(deepcopy(request)) + register_network(network) + for request in root.iterfind("./request"): + rspec.append(deepcopy(request)) return etree.tostring(rspec, xml_declaration=True, pretty_print=True) class RSpec: