示例#1
0
    def __init__(self, name, locator, 
                 key="", cert="", root_cert="", domain_verify=True):

        self.transports = TransportFactory(key, cert, root_cert, domain_verify)

        # Log init messages from TransportFactory
        self.transports.log_details(log, "AviaryOperations")
        self.name = name

        # Put this here to be referenced by AviaryOperations types
        self.locator = locator

        self.type_to_aviary = self._type_to_aviary()
        self.aviary_to_type = self._aviary_to_type()
示例#2
0
    def __init__(self, datadir, locator_uri,
                 key="", cert="", root_cert="", domain_verify=True):
        '''
        Initialize AviaryLocator so that get_endpoints may be used.
       
        datadir -- the directory containing a wsdl file for the locator

        locator_uri -- the URI used to the Aviary locator.
        There are sane defaults for scheme, port and path so only
        the hostname is required.  Defaults are http, 9000, and 
        'services/locator/locate' respectively.
        '''
        self.transport = TransportFactory(key, cert, root_cert, domain_verify)
        self.scheme, self.locator_uri = self._get_uri(locator_uri)
        self.datadir = datadir
        self.wsdl = "file:" + os.path.join(self.datadir, "aviary-locator.wsdl")
        log.info("AviaryLocator:  locator URL set to %s" % self.locator_uri)
示例#3
0
class AviaryLocator(object):    
    def __init__(self, datadir, locator_uri,
                 key="", cert="", root_cert="", domain_verify=True):
        '''
        Initialize AviaryLocator so that get_endpoints may be used.
       
        datadir -- the directory containing a wsdl file for the locator

        locator_uri -- the URI used to the Aviary locator.
        There are sane defaults for scheme, port and path so only
        the hostname is required.  Defaults are http, 9000, and 
        'services/locator/locate' respectively.
        '''
        self.transport = TransportFactory(key, cert, root_cert, domain_verify)
        self.scheme, self.locator_uri = self._get_uri(locator_uri)
        self.datadir = datadir
        self.wsdl = "file:" + os.path.join(self.datadir, "aviary-locator.wsdl")
        log.info("AviaryLocator:  locator URL set to %s" % self.locator_uri)

    def _get_uri(self, locator):
        uri = parse_URL(locator)
        # Fill in scheme, port, path if they are blank
        if uri.scheme is None:
            uri.scheme = "http"
        if uri.port is None:
            uri.port = "9000"
        if uri.path is None:
            uri.path = "services/locator/locate"
        return uri.scheme, str(uri)
        
    def get_endpoints(self, resource, sub_type):
        '''
        Return endpoints from Aviary for the resource and sub_type.
        See documentation on the Aviary locator for information on
        legal values for resource and sub_type.
        '''
        the_transport = self.transport.get_transport(self.scheme)
        client = OverrideClient(self.wsdl, cache=None)
        client.set_options(location=self.locator_uri,
                           transport=the_transport)
        res_id = client.factory.create("ns0:ResourceID")
        res_id.resource = resource
        res_id.sub_type = sub_type
        res_id.name = None
        return client.service.locate(res_id)
示例#4
0
class _AviaryCommon(object):
    def __init__(self, name, locator, 
                 key="", cert="", root_cert="", domain_verify=True):

        self.transports = TransportFactory(key, cert, root_cert, domain_verify)

        # Log init messages from TransportFactory
        self.transports.log_details(log, "AviaryOperations")
        self.name = name

        # Put this here to be referenced by AviaryOperations types
        self.locator = locator

        self.type_to_aviary = self._type_to_aviary()
        self.aviary_to_type = self._aviary_to_type()

    def get_datadir(self, datadir, subdir):
        if not type(datadir) in (tuple, list):
            datadir = [datadir]

        # Find the first element in datadir that is a valid
        # path.  If the path has a subdirectory called 
        # "subdir", consider that part of the path.
        for d in datadir:
            if os.path.isdir(d):
                s = os.path.join(d, subdir)
                if os.path.isdir(s):
                    return s
                return d
        # Hmm, well, just return the first one since we're
        # going to get an error anyway.
        return datadir[0]

    @classmethod
    def _type_to_aviary(cls):
        # Need to be able to turn simple Python types into Aviary types for attributes
        return {int: "INTEGER", float: "FLOAT", str: "STRING", bool: "BOOLEAN"}

    @classmethod
    def _aviary_to_type(cls):
        return {"INTEGER": int, "FLOAT": float, "STRING": str, "BOOLEAN": bool}

    def _set_client_info(self, client, refresh=False):
        scheme, host = client.server_list.find_server(client.service_name, 
                                                      refresh)

        # Have to set the URL for the method.  This might go away someday...
        client.set_options(location=host+client.method_name)

        # Since we pool the clients and reuse them for different requests
        # and since its possible to be using servers with different schemes,
        # we have to always reset the transport here.
        the_transport = self.transports.get_transport(scheme)
        client.set_options(transport=the_transport)

    def _setup_client(self, client, server_list, name, meth_name):
        # Look up the host and construct the URL.
        # Store information in the client so that retry is possible.
        client.server_list = server_list
        client.service_name = name
        client.method_name = meth_name

        # This is initial setup before a call so we want to try a 
        # refresh on the server list if our service comes up missing
        self._set_client_info(client, refresh="on_no_host")
        return client

    @classmethod
    def _get_status(cls, result):
        # For Aviary operations, if the operation
        # did not work the reason is in the text field.
        # In cumin, we want to pass any error text as
        # the status parameter to callbacks
        if result.code != "OK":
            return result.text
        return result.code

    @classmethod
    def _cb_args_dataless(cls, result):
        # Marshal data in result for passing to standard callback.
        # This routine is for results that contain status only, no data.
        if isinstance(result, Exception):
            status = result
        else:
            status = _AviaryCommon._get_status(result)
        return (status, None)

    @classmethod
    def _pretty_result(cls, result, host):
        if isinstance(result, urllib2.URLError):
            return Exception("Trouble reaching host %s, %s" % (host, result.reason))
        elif isinstance(result, Exception):
            if hasattr(result, "args"):
                reason = result.args
            else:
                reason = str(result)
            return Exception("Operation failed on host %s, %s" % (host, reason))
        return result

    def call_client_retry(self, client, meth_name, *meth_args, **meth_kwargs):
        # If we fail with a urllib2.URLError (or anything similar) then try
        # attempt to get a new endpoint and try again.
        meth = getattr(client.service, meth_name)
        try:
            result = meth(*meth_args, **meth_kwargs)
        except Exception, e:
            # If we get an exception, our endpoint may have moved 
            # (probably due to a restart on the condor side)
            # Let's get new endpoints, reset the client, 
            # and try again.
            if client.server_list.should_retry:
                log.debug("AviaryOperations: received %s, retrying %s"\
                              % (str(e), client.options.location))
                self._set_client_info(client, refresh=True)
                result = meth(*meth_args, **meth_kwargs)
            else:
                raise e
        return result