def __init__(self, url=None, **options): """ Creates a connection. A newly created connection must be opened with the Connection.open() method before it can be used. @type url: str @param url: [ <username> [ / <password> ] @ ] <host> [ : <port> ] @type host: str @param host: the name or ip address of the remote host (overriden by url) @type port: int @param port: the port number of the remote host (overriden by url) @type transport: str @param transport: one of tcp, tcp+tls, or ssl (alias for tcp+tls) @type heartbeat: int @param heartbeat: heartbeat interval in seconds @type username: str @param username: the username for authentication (overriden by url) @type password: str @param password: the password for authentication (overriden by url) @type sasl_mechanisms: str @param sasl_mechanisms: space separated list of permitted sasl mechanisms @type sasl_service: str @param sasl_service: the service name if needed by the SASL mechanism in use @type sasl_min_ssf: int @param sasl_min_ssf: the minimum acceptable security strength factor @type sasl_max_ssf: int @param sasl_max_ssf: the maximum acceptable security strength factor @type reconnect: bool @param reconnect: enable/disable automatic reconnect @type reconnect_timeout: float @param reconnect_timeout: total time to attempt reconnect @type reconnect_interval_min: float @param reconnect_interval_min: minimum interval between reconnect attempts @type reconnect_interval_max: float @param reconnect_interval_max: maximum interval between reconnect attempts @type reconnect_interval: float @param reconnect_interval: set both min and max reconnect intervals @type reconnect_limit: int @param reconnect_limit: limit the total number of reconnect attempts @type reconnect_urls: list[str] @param reconnect_urls: list of backup hosts specified as urls @type address_ttl: float @param address_ttl: time until cached address resolution expires @type ssl_keyfile: str @param ssl_keyfile: file with client's private key (PEM format) @type ssl_certfile: str @param ssl_certfile: file with client's public (eventually priv+pub) key (PEM format) @type ssl_trustfile: str @param ssl_trustfile: file trusted certificates to validate the server @type ssl_skip_hostname_check: bool @param ssl_skip_hostname_check: disable verification of hostname in certificate. Use with caution - disabling hostname checking leaves you vulnerable to Man-in-the-Middle attacks. @rtype: Connection @return: a disconnected Connection """ if url is None: url = options.get("host") if isinstance(url, basestring): url = URL(url) self.host = url.host if options.has_key("transport"): self.transport = options.get("transport") elif url.scheme == url.AMQP: self.transport = "tcp" elif url.scheme == url.AMQPS: self.transport = "ssl" else: self.transport = "tcp" if self.transport in ("ssl", "tcp+tls"): self.port = default(url.port, options.get("port", AMQPS_PORT)) else: self.port = default(url.port, options.get("port", AMQP_PORT)) self.heartbeat = options.get("heartbeat") self.username = default(url.user, options.get("username", None)) self.password = default(url.password, options.get("password", None)) self.auth_username = None self.sasl_mechanisms = options.get("sasl_mechanisms") self.sasl_service = options.get("sasl_service", "qpidd") self.sasl_min_ssf = options.get("sasl_min_ssf") self.sasl_max_ssf = options.get("sasl_max_ssf") self.reconnect = options.get("reconnect", False) self.reconnect_timeout = options.get("reconnect_timeout") reconnect_interval = options.get("reconnect_interval") self.reconnect_interval_min = options.get("reconnect_interval_min", default(reconnect_interval, 1)) self.reconnect_interval_max = options.get("reconnect_interval_max", default(reconnect_interval, 2 * 60)) self.reconnect_limit = options.get("reconnect_limit") self.reconnect_urls = options.get("reconnect_urls", []) self.reconnect_log = options.get("reconnect_log", True) self.address_ttl = options.get("address_ttl", 60) self.tcp_nodelay = options.get("tcp_nodelay", False) self.ssl_keyfile = options.get("ssl_keyfile", None) self.ssl_certfile = options.get("ssl_certfile", None) self.ssl_trustfile = options.get("ssl_trustfile", None) self.ssl_skip_hostname_check = options.get("ssl_skip_hostname_check", False) self.client_properties = options.get("client_properties", {}) self.options = options self.id = str(uuid4()) self.session_counter = 0 self.sessions = {} self._open = False self._connected = False self._transport_connected = False self._lock = RLock() self._condition = Condition(self._lock) self._waiter = Waiter(self._condition) self._modcount = Serial(0) self.error = None from driver import Driver self._driver = Driver(self)
def __init__(self, url=None, **options): """ Creates a connection. A newly created connection must be connected with the Connection.connect() method before it can be used. @type url: str @param url: [ <username> [ / <password> ] @ ] <host> [ : <port> ] @type host: str @param host: the name or ip address of the remote host (overriden by url) @type port: int @param port: the port number of the remote host (overriden by url) @type transport: str @param transport: one of tcp, tcp+tls, or ssl (alias for tcp+tls) @type heartbeat: int @param heartbeat: heartbeat interval in seconds @type username: str @param username: the username for authentication (overriden by url) @type password: str @param password: the password for authentication (overriden by url) @type sasl_mechanisms: str @param sasl_mechanisms: space separated list of permitted sasl mechanisms @type sasl_service: str @param sasl_service: ??? @type sasl_min_ssf: ??? @param sasl_min_ssf: ??? @type sasl_max_ssf: ??? @param sasl_max_ssf: ??? @type reconnect: bool @param reconnect: enable/disable automatic reconnect @type reconnect_timeout: float @param reconnect_timeout: total time to attempt reconnect @type reconnect_internal_min: float @param reconnect_internal_min: minimum interval between reconnect attempts @type reconnect_internal_max: float @param reconnect_internal_max: maximum interval between reconnect attempts @type reconnect_internal: float @param reconnect_interval: set both min and max reconnect intervals @type reconnect_limit: int @param reconnect_limit: limit the total number of reconnect attempts @type reconnect_urls: list[str] @param reconnect_urls: list of backup hosts specified as urls @type address_ttl: float @param address_ttl: time until cached address resolution expires @type ssl_keyfile: str @param ssl_keyfile: file with client's private key (PEM format) @type ssl_certfile: str @param ssl_certfile: file with client's public (eventually priv+pub) key (PEM format) @type ssl_trustfile: str @param ssl_trustfile: file trusted certificates to validate the server @rtype: Connection @return: a disconnected Connection """ if url is None: url = options.get("host") if isinstance(url, basestring): url = URL(url) self.host = url.host if options.has_key("transport"): self.transport = options.get("transport") elif url.scheme == url.AMQP: self.transport = "tcp" elif url.scheme == url.AMQPS: self.transport = "ssl" else: self.transport = "tcp" if self.transport in ("ssl", "tcp+tls"): self.port = default(url.port, options.get("port", AMQPS_PORT)) else: self.port = default(url.port, options.get("port", AMQP_PORT)) self.heartbeat = options.get("heartbeat") self.username = default(url.user, options.get("username", None)) self.password = default(url.password, options.get("password", None)) self.auth_username = None self.sasl_mechanisms = options.get("sasl_mechanisms") self.sasl_service = options.get("sasl_service", "qpidd") self.sasl_min_ssf = options.get("sasl_min_ssf") self.sasl_max_ssf = options.get("sasl_max_ssf") self.reconnect = options.get("reconnect", False) self.reconnect_timeout = options.get("reconnect_timeout") reconnect_interval = options.get("reconnect_interval") self.reconnect_interval_min = options.get("reconnect_interval_min", default(reconnect_interval, 1)) self.reconnect_interval_max = options.get("reconnect_interval_max", default(reconnect_interval, 2*60)) self.reconnect_limit = options.get("reconnect_limit") self.reconnect_urls = options.get("reconnect_urls", []) self.reconnect_log = options.get("reconnect_log", True) self.address_ttl = options.get("address_ttl", 60) self.tcp_nodelay = options.get("tcp_nodelay", False) self.ssl_keyfile = options.get("ssl_keyfile", None) self.ssl_certfile = options.get("ssl_certfile", None) self.ssl_trustfile = options.get("ssl_trustfile", None) self.client_properties = options.get("client_properties", {}) self.options = options self.id = str(uuid4()) self.session_counter = 0 self.sessions = {} self._open = False self._connected = False self._transport_connected = False self._lock = RLock() self._condition = Condition(self._lock) self._waiter = Waiter(self._condition) self._modcount = Serial(0) self.error = None from driver import Driver self._driver = Driver(self)
class Connection(Endpoint): """ A Connection manages a group of L{Sessions<Session>} and connects them with a remote endpoint. """ @static def establish(url=None, timeout=None, **options): """ Constructs a L{Connection} with the supplied parameters and opens it. """ conn = Connection(url, **options) conn.open(timeout=timeout) return conn def __init__(self, url=None, **options): """ Creates a connection. A newly created connection must be opened with the Connection.open() method before it can be used. @type url: str @param url: [ <username> [ / <password> ] @ ] <host> [ : <port> ] @type host: str @param host: the name or ip address of the remote host (overriden by url) @type port: int @param port: the port number of the remote host (overriden by url) @type transport: str @param transport: one of tcp, tcp+tls, or ssl (alias for tcp+tls) @type heartbeat: int @param heartbeat: heartbeat interval in seconds @type username: str @param username: the username for authentication (overriden by url) @type password: str @param password: the password for authentication (overriden by url) @type sasl_mechanisms: str @param sasl_mechanisms: space separated list of permitted sasl mechanisms @type sasl_service: str @param sasl_service: the service name if needed by the SASL mechanism in use @type sasl_min_ssf: int @param sasl_min_ssf: the minimum acceptable security strength factor @type sasl_max_ssf: int @param sasl_max_ssf: the maximum acceptable security strength factor @type reconnect: bool @param reconnect: enable/disable automatic reconnect @type reconnect_timeout: float @param reconnect_timeout: total time to attempt reconnect @type reconnect_interval_min: float @param reconnect_interval_min: minimum interval between reconnect attempts @type reconnect_interval_max: float @param reconnect_interval_max: maximum interval between reconnect attempts @type reconnect_interval: float @param reconnect_interval: set both min and max reconnect intervals @type reconnect_limit: int @param reconnect_limit: limit the total number of reconnect attempts @type reconnect_urls: list[str] @param reconnect_urls: list of backup hosts specified as urls @type address_ttl: float @param address_ttl: time until cached address resolution expires @type ssl_keyfile: str @param ssl_keyfile: file with client's private key (PEM format) @type ssl_certfile: str @param ssl_certfile: file with client's public (eventually priv+pub) key (PEM format) @type ssl_trustfile: str @param ssl_trustfile: file trusted certificates to validate the server @type ssl_skip_hostname_check: bool @param ssl_skip_hostname_check: disable verification of hostname in certificate. Use with caution - disabling hostname checking leaves you vulnerable to Man-in-the-Middle attacks. @rtype: Connection @return: a disconnected Connection """ if url is None: url = options.get("host") if isinstance(url, basestring): url = URL(url) self.host = url.host if options.has_key("transport"): self.transport = options.get("transport") elif url.scheme == url.AMQP: self.transport = "tcp" elif url.scheme == url.AMQPS: self.transport = "ssl" else: self.transport = "tcp" if self.transport in ("ssl", "tcp+tls"): self.port = default(url.port, options.get("port", AMQPS_PORT)) else: self.port = default(url.port, options.get("port", AMQP_PORT)) self.heartbeat = options.get("heartbeat") self.username = default(url.user, options.get("username", None)) self.password = default(url.password, options.get("password", None)) self.auth_username = None self.sasl_mechanisms = options.get("sasl_mechanisms") self.sasl_service = options.get("sasl_service", "qpidd") self.sasl_min_ssf = options.get("sasl_min_ssf") self.sasl_max_ssf = options.get("sasl_max_ssf") self.reconnect = options.get("reconnect", False) self.reconnect_timeout = options.get("reconnect_timeout") reconnect_interval = options.get("reconnect_interval") self.reconnect_interval_min = options.get("reconnect_interval_min", default(reconnect_interval, 1)) self.reconnect_interval_max = options.get("reconnect_interval_max", default(reconnect_interval, 2 * 60)) self.reconnect_limit = options.get("reconnect_limit") self.reconnect_urls = options.get("reconnect_urls", []) self.reconnect_log = options.get("reconnect_log", True) self.address_ttl = options.get("address_ttl", 60) self.tcp_nodelay = options.get("tcp_nodelay", False) self.ssl_keyfile = options.get("ssl_keyfile", None) self.ssl_certfile = options.get("ssl_certfile", None) self.ssl_trustfile = options.get("ssl_trustfile", None) self.ssl_skip_hostname_check = options.get("ssl_skip_hostname_check", False) self.client_properties = options.get("client_properties", {}) self.options = options self.id = str(uuid4()) self.session_counter = 0 self.sessions = {} self._open = False self._connected = False self._transport_connected = False self._lock = RLock() self._condition = Condition(self._lock) self._waiter = Waiter(self._condition) self._modcount = Serial(0) self.error = None from driver import Driver self._driver = Driver(self) def _wait(self, predicate, timeout=None): return self._waiter.wait(predicate, timeout=timeout) def _wakeup(self): self._modcount += 1 self._driver.wakeup() def check_error(self): if self.error: self._condition.gc() e = self.error if isinstance(e, ContentError): """ forget the content error. It will be raised this time but won't block future calls """ self.error = None raise e def get_error(self): return self.error def _ewait(self, predicate, timeout=None): result = self._wait(lambda: self.error or predicate(), timeout) self.check_error() return result def check_closed(self): if not self._connected: self._condition.gc() raise ConnectionClosed() @synchronized def session(self, name=None, transactional=False): """ Creates or retrieves the named session. If the name is omitted or None, then a unique name is chosen based on a randomly generated uuid. @type name: str @param name: the session name @rtype: Session @return: the named Session """ if name is None: name = "%s:%s" % (self.id, self.session_counter) self.session_counter += 1 else: name = "%s:%s" % (self.id, name) if self.sessions.has_key(name): return self.sessions[name] else: ssn = Session(self, name, transactional) self.sessions[name] = ssn self._wakeup() return ssn @synchronized def _remove_session(self, ssn): self.sessions.pop(ssn.name, 0) @synchronized def open(self, timeout=None): """ Opens a connection. """ if self._open: raise ConnectionError("already open") self._open = True if self.reconnect and self.reconnect_timeout > 0: timeout = self.reconnect_timeout self.attach(timeout=timeout) @synchronized def opened(self): """ Return true if the connection is open, false otherwise. """ return self._open @synchronized def attach(self, timeout=None): """ Attach to the remote endpoint. """ if not self._connected: self._connected = True self._driver.start() self._wakeup() if not self._ewait(lambda: self._transport_connected and not self._unlinked(), timeout=timeout): self.reconnect = False raise Timeout("Connection attach timed out") def _unlinked(self): return [ l for ssn in self.sessions.values() if not (ssn.error or ssn.closed) for l in ssn.senders + ssn.receivers if not (l.linked or l.error or l.closed) ] @synchronized def detach(self, timeout=None): """ Detach from the remote endpoint. """ if self._connected: self._connected = False self._wakeup() cleanup = True else: cleanup = False try: if not self._wait(lambda: not self._transport_connected, timeout=timeout): raise Timeout("detach timed out") finally: if cleanup: self._driver.stop() self._condition.gc() @synchronized def attached(self): """ Return true if the connection is attached, false otherwise. """ return self._connected @synchronized def close(self, timeout=None): """ Close the connection and all sessions. """ try: for ssn in self.sessions.values(): ssn.close(timeout=timeout) finally: self.detach(timeout=timeout) self._open = False
class Connection(Endpoint): """ A Connection manages a group of L{Sessions<Session>} and connects them with a remote endpoint. """ @static def establish(url=None, **options): """ Constructs a L{Connection} with the supplied parameters and opens it. """ conn = Connection(url, **options) conn.open() return conn def __init__(self, url=None, **options): """ Creates a connection. A newly created connection must be connected with the Connection.connect() method before it can be used. @type url: str @param url: [ <username> [ / <password> ] @ ] <host> [ : <port> ] @type host: str @param host: the name or ip address of the remote host (overriden by url) @type port: int @param port: the port number of the remote host (overriden by url) @type transport: str @param transport: one of tcp, tcp+tls, or ssl (alias for tcp+tls) @type heartbeat: int @param heartbeat: heartbeat interval in seconds @type username: str @param username: the username for authentication (overriden by url) @type password: str @param password: the password for authentication (overriden by url) @type sasl_mechanisms: str @param sasl_mechanisms: space separated list of permitted sasl mechanisms @type sasl_service: str @param sasl_service: ??? @type sasl_min_ssf: ??? @param sasl_min_ssf: ??? @type sasl_max_ssf: ??? @param sasl_max_ssf: ??? @type reconnect: bool @param reconnect: enable/disable automatic reconnect @type reconnect_timeout: float @param reconnect_timeout: total time to attempt reconnect @type reconnect_internal_min: float @param reconnect_internal_min: minimum interval between reconnect attempts @type reconnect_internal_max: float @param reconnect_internal_max: maximum interval between reconnect attempts @type reconnect_internal: float @param reconnect_interval: set both min and max reconnect intervals @type reconnect_limit: int @param reconnect_limit: limit the total number of reconnect attempts @type reconnect_urls: list[str] @param reconnect_urls: list of backup hosts specified as urls @type address_ttl: float @param address_ttl: time until cached address resolution expires @type ssl_keyfile: str @param ssl_keyfile: file with client's private key (PEM format) @type ssl_certfile: str @param ssl_certfile: file with client's public (eventually priv+pub) key (PEM format) @type ssl_trustfile: str @param ssl_trustfile: file trusted certificates to validate the server @rtype: Connection @return: a disconnected Connection """ if url is None: url = options.get("host") if isinstance(url, basestring): url = URL(url) self.host = url.host if options.has_key("transport"): self.transport = options.get("transport") elif url.scheme == url.AMQP: self.transport = "tcp" elif url.scheme == url.AMQPS: self.transport = "ssl" else: self.transport = "tcp" if self.transport in ("ssl", "tcp+tls"): self.port = default(url.port, options.get("port", AMQPS_PORT)) else: self.port = default(url.port, options.get("port", AMQP_PORT)) self.heartbeat = options.get("heartbeat") self.username = default(url.user, options.get("username", None)) self.password = default(url.password, options.get("password", None)) self.auth_username = None self.sasl_mechanisms = options.get("sasl_mechanisms") self.sasl_service = options.get("sasl_service", "qpidd") self.sasl_min_ssf = options.get("sasl_min_ssf") self.sasl_max_ssf = options.get("sasl_max_ssf") self.reconnect = options.get("reconnect", False) self.reconnect_timeout = options.get("reconnect_timeout") reconnect_interval = options.get("reconnect_interval") self.reconnect_interval_min = options.get("reconnect_interval_min", default(reconnect_interval, 1)) self.reconnect_interval_max = options.get("reconnect_interval_max", default(reconnect_interval, 2*60)) self.reconnect_limit = options.get("reconnect_limit") self.reconnect_urls = options.get("reconnect_urls", []) self.reconnect_log = options.get("reconnect_log", True) self.address_ttl = options.get("address_ttl", 60) self.tcp_nodelay = options.get("tcp_nodelay", False) self.ssl_keyfile = options.get("ssl_keyfile", None) self.ssl_certfile = options.get("ssl_certfile", None) self.ssl_trustfile = options.get("ssl_trustfile", None) self.client_properties = options.get("client_properties", {}) self.options = options self.id = str(uuid4()) self.session_counter = 0 self.sessions = {} self._open = False self._connected = False self._transport_connected = False self._lock = RLock() self._condition = Condition(self._lock) self._waiter = Waiter(self._condition) self._modcount = Serial(0) self.error = None from driver import Driver self._driver = Driver(self) def _wait(self, predicate, timeout=None): return self._waiter.wait(predicate, timeout=timeout) def _wakeup(self): self._modcount += 1 self._driver.wakeup() def check_error(self): if self.error: self._condition.gc() raise self.error def get_error(self): return self.error def _ewait(self, predicate, timeout=None): result = self._wait(lambda: self.error or predicate(), timeout) self.check_error() return result def check_closed(self): if not self._connected: self._condition.gc() raise ConnectionClosed() @synchronized def session(self, name=None, transactional=False): """ Creates or retrieves the named session. If the name is omitted or None, then a unique name is chosen based on a randomly generated uuid. @type name: str @param name: the session name @rtype: Session @return: the named Session """ if name is None: name = "%s:%s" % (self.id, self.session_counter) self.session_counter += 1 else: name = "%s:%s" % (self.id, name) if self.sessions.has_key(name): return self.sessions[name] else: ssn = Session(self, name, transactional) self.sessions[name] = ssn self._wakeup() return ssn @synchronized def _remove_session(self, ssn): self.sessions.pop(ssn.name, 0) @synchronized def open(self): """ Opens a connection. """ if self._open: raise ConnectionError("already open") self._open = True self.attach() @synchronized def opened(self): """ Return true if the connection is open, false otherwise. """ return self._open @synchronized def attach(self): """ Attach to the remote endpoint. """ if not self._connected: self._connected = True self._driver.start() self._wakeup() self._ewait(lambda: self._transport_connected and not self._unlinked()) def _unlinked(self): return [l for ssn in self.sessions.values() if not (ssn.error or ssn.closed) for l in ssn.senders + ssn.receivers if not (l.linked or l.error or l.closed)] @synchronized def detach(self, timeout=None): """ Detach from the remote endpoint. """ if self._connected: self._connected = False self._wakeup() cleanup = True else: cleanup = False try: if not self._wait(lambda: not self._transport_connected, timeout=timeout): raise Timeout("detach timed out") finally: if cleanup: self._driver.stop() self._condition.gc() @synchronized def attached(self): """ Return true if the connection is attached, false otherwise. """ return self._connected @synchronized def close(self, timeout=None): """ Close the connection and all sessions. """ try: for ssn in self.sessions.values(): ssn.close(timeout=timeout) finally: self.detach(timeout=timeout) self._open = False