Merge branch 'master' of ssh://git.onelab.eu/git/sfa
[sfa.git] / sfa / server / interface.py
index 8e5822e..0804fc1 100644 (file)
@@ -5,15 +5,13 @@
 
 from sfa.util.faults import *
 from sfa.util.storage import *
 
 from sfa.util.faults import *
 from sfa.util.storage import *
-from sfa.util.namespace import *
+from sfa.util.xrn import get_authority, hrn_to_urn
 from sfa.trust.gid import GID
 from sfa.trust.gid import GID
-from sfa.util.table import SfaTable
 from sfa.util.record import SfaRecord
 import traceback
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 import sfa.util.soapprotocol as soapprotocol
 
 from sfa.util.record import SfaRecord
 import traceback
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 import sfa.util.soapprotocol as soapprotocol
 
 # GeniLight client support is optional
 try:
     from egeni.geniLight_client import *
 # GeniLight client support is optional
 try:
     from egeni.geniLight_client import *
@@ -46,10 +44,9 @@ class Interfaces(dict):
     # defined by the class 
     default_dict = {}
 
     # defined by the class 
     default_dict = {}
 
-    # allowed types
-    types = ['sa', 'ma']
+    types = ['authority']
 
 
-    def __init__(self, api, conf_file, type):
+    def __init__(self, api, conf_file, type='authority'):
         if type not in self.types:
             raise SfaInfaildArgument('Invalid type %s: must be in %s' % (type, self.types))    
         dict.__init__(self, {})
         if type not in self.types:
             raise SfaInfaildArgument('Invalid type %s: must be in %s' % (type, self.types))    
         dict.__init__(self, {})
@@ -61,12 +58,26 @@ class Interfaces(dict):
         interfaces = self.interface_info.values()[0].values()[0]
         if not isinstance(interfaces, list):
             interfaces = [self.interfaces]
         interfaces = self.interface_info.values()[0].values()[0]
         if not isinstance(interfaces, list):
             interfaces = [self.interfaces]
+        # set the url and urn 
+        for interface in interfaces:
+            hrn, address, port = interface['hrn'], interface['addr'], interface['port']
+            url = 'http://%(address)s:%(port)s' % locals()
+            interface['url'] = url
+            interface['urn'] = hrn_to_urn(hrn, 'authority')
+    
         self.interfaces = {}
         self.interfaces = {}
+        required_fields = self.default_fields.keys()
         for interface in interfaces:
         for interface in interfaces:
-            self.interfaces[interface['hrn']] = interface
+            valid = True
+            # skp any interface definition that has a null hrn, 
+            # address or port
+            for field in required_fields:
+                if field not in interface or not interface[field]:
+                    valid = False
+                    break
+            if valid:     
+                self.interfaces[interface['hrn']] = interface
 
 
-        # get connections
-        self.update(self.get_connections(self.interfaces))
 
     def sync_interfaces(self):
         """
 
     def sync_interfaces(self):
         """
@@ -81,8 +92,8 @@ class Interfaces(dict):
         hrns_current = [gid.get_hrn() for gid in gids_current] 
         hrns_expected = self.interfaces.keys() 
         new_hrns = set(hrns_expected).difference(hrns_current)
         hrns_current = [gid.get_hrn() for gid in gids_current] 
         hrns_expected = self.interfaces.keys() 
         new_hrns = set(hrns_expected).difference(hrns_current)
-        gids = self.get_peer_gids(new_hrns)
-        # update the local db records for these registries
+        gids = self.get_peer_gids(new_hrns) + gids_current
+        # make sure there is a record for every gid
         self.update_db_records(self.type, gids)
         
     def get_peer_gids(self, new_hrns):
         self.update_db_records(self.type, gids)
         
     def get_peer_gids(self, new_hrns):
@@ -94,13 +105,15 @@ class Interfaces(dict):
             return peer_gids
         trusted_certs_dir = self.api.config.get_trustedroots_dir()
         for new_hrn in new_hrns:
             return peer_gids
         trusted_certs_dir = self.api.config.get_trustedroots_dir()
         for new_hrn in new_hrns:
+            if not new_hrn:
+                continue
             # the gid for this interface should already be installed  
             if new_hrn == self.api.config.SFA_INTERFACE_HRN:
                 continue
             try:
                 # get gid from the registry
                 interface_info =  self.interfaces[new_hrn]
             # the gid for this interface should already be installed  
             if new_hrn == self.api.config.SFA_INTERFACE_HRN:
                 continue
             try:
                 # get gid from the registry
                 interface_info =  self.interfaces[new_hrn]
-                interface = self.get_connections(self.interfaces[new_hrn])[new_hrn]
+                interface = self[new_hrn]
                 trusted_gids = interface.get_trusted_certs()
                 if trusted_gids:
                     # the gid we want shoudl be the first one in the list, 
                 trusted_gids = interface.get_trusted_certs()
                 if trusted_gids:
                     # the gid we want shoudl be the first one in the list, 
@@ -122,8 +135,7 @@ class Interfaces(dict):
             except:
                 message = "interface: %s\tunable to install trusted gid for %s" % \
                             (self.api.interface, new_hrn) 
             except:
                 message = "interface: %s\tunable to install trusted gid for %s" % \
                             (self.api.interface, new_hrn) 
-                self.api.logger.info(message)
-                traceback.print_exc()
+                self.api.logger.log_exc(message)
         
         # reload the trusted certs list
         self.api.auth.load_trusted_certs()
         
         # reload the trusted certs list
         self.api.auth.load_trusted_certs()
@@ -135,22 +147,23 @@ class Interfaces(dict):
         defined in the config file (registries.xml). Removes old records from
         the db.         
         """
         defined in the config file (registries.xml). Removes old records from
         the db.         
         """
+        # import SfaTable here so this module can be loaded by ComponentAPI 
+        from sfa.util.table import SfaTable
         if not gids: 
             return
         if not gids: 
             return
-        # get hrns we expect to find
-        # ignore records for local interfaces
-        ignore_interfaces = [self.api.config.SFA_INTERFACE_HRN]
-        hrns_expected = [gid.get_hrn() for gid in gids \
-                         if gid.get_hrn() not in ignore_interfaces]
+        
+        # hrns that should have a record
+        hrns_expected = [gid.get_hrn() for gid in gids]
 
         # get hrns that actually exist in the db
         table = SfaTable()
 
         # get hrns that actually exist in the db
         table = SfaTable()
-        records = table.find({'type': type})
+        records = table.find({'type': type, 'pointer': -1})
         hrns_found = [record['hrn'] for record in records]
         hrns_found = [record['hrn'] for record in records]
-       
+      
         # remove old records
         for record in records:
         # remove old records
         for record in records:
-            if record['hrn'] not in hrns_expected:
+            if record['hrn'] not in hrns_expected and \
+                record['hrn'] != self.api.config.SFA_INTERFACE_HRN:
                 table.remove(record)
 
         # add new records
                 table.remove(record)
 
         # add new records
@@ -167,22 +180,17 @@ class Interfaces(dict):
                 record = SfaRecord(dict=record)
                 table.insert(record)
                         
                 record = SfaRecord(dict=record)
                 table.insert(record)
                         
-    def get_connections(self, interfaces):
+    def get_connections(self):
         """
         read connection details for the trusted peer registries from file return 
         a dictionary of connections keyed on interface hrn. 
         """
         connections = {}
         required_fields = self.default_fields.keys()
         """
         read connection details for the trusted peer registries from file return 
         a dictionary of connections keyed on interface hrn. 
         """
         connections = {}
         required_fields = self.default_fields.keys()
-        if not isinstance(interfaces, list):
-            interfaces = [interfaces]
-        for interface in interfaces:
+        for interface in self.interfaces.values():
             # make sure the required fields are present and not null
             # make sure the required fields are present and not null
-            if not all([interface.get(key) for key in required_fields]):
-                continue
-            hrn, address, port = interface['hrn'], interface['addr'], interface['port']
-            url = 'http://%(address)s:%(port)s' % locals()
+            
+            url = interface['url']
             # check which client we should use
             # sfa.util.xmlrpcprotocol is default
             client_type = 'xmlrpcprotocol'
             # check which client we should use
             # sfa.util.xmlrpcprotocol is default
             client_type = 'xmlrpcprotocol'
@@ -192,6 +200,6 @@ class Interfaces(dict):
                 client_type = 'geniclientlight'
                 connections[hrn] = GeniClientLight(url, self.api.key_file, self.api.cert_file) 
             else:
                 client_type = 'geniclientlight'
                 connections[hrn] = GeniClientLight(url, self.api.key_file, self.api.cert_file) 
             else:
-                connections[hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
+                connections[interface['hrn']] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
 
         return connections 
 
         return connections