def test_pool_config_consume_and_then_consume_again(): test_config = dict(test_pool_config) consumed_pool_config = PoolConfig.consume(test_config) assert consumed_pool_config.encrypted is False consumed_pool_config.encrypted = "test" with pytest.raises(AttributeError): consumed_pool_config = PoolConfig.consume(consumed_pool_config) consumed_pool_config = PoolConfig.consume( dict(consumed_pool_config.items())) consumed_pool_config = PoolConfig.consume( dict(consumed_pool_config.items())) assert consumed_pool_config.encrypted == "test"
def open(cls, address, *, auth=None, timeout=None, **config): """ Open a new Bolt connection to a given server address. :param address: :param auth: :param timeout: :param config: :return: """ config = PoolConfig.consume(config) s, config.protocol_version = connect(address, timeout=timeout, config=config) if config.protocol_version == (3, 0): from neo4j.io._bolt3 import Bolt3 connection = Bolt3(address, s, auth=auth, **config) else: log.debug("[#%04X] S: <CLOSE>", s.getpeername()[1]) s.shutdown(SHUT_RDWR) s.close() raise ProtocolError( "Driver does not support Bolt protocol version: 0x%06X%02X", config.protocol_version[0], config.protocol_version[1]) connection.hello() return connection
def open(cls, address, *, auth=None, timeout=None, **pool_config): """ Open a new Bolt connection to a given server address. :param address: :param auth: :param timeout: The connection timeout :param pool_config: :return: :raise BoltHandshakeError: raised if the Bolt Protocol can not negotiate a protocol version. :raise ServiceUnavailable: raised if there was a connection issue. """ pool_config = PoolConfig.consume(pool_config) s, pool_config.protocol_version, handshake, data = connect( address, timeout=timeout, custom_resolver=pool_config.resolver, ssl_context=pool_config.get_ssl_context(), keep_alive=pool_config.keep_alive, ) if pool_config.protocol_version == (3, 0): # Carry out Bolt subclass imports locally to avoid circular dependency issues. from neo4j.io._bolt3 import Bolt3 connection = Bolt3(address, s, pool_config.max_connection_lifetime, auth=auth, user_agent=pool_config.user_agent) elif pool_config.protocol_version == (4, 0): # Carry out Bolt subclass imports locally to avoid circular dependency issues. from neo4j.io._bolt4x0 import Bolt4x0 connection = Bolt4x0(address, s, pool_config.max_connection_lifetime, auth=auth, user_agent=pool_config.user_agent) elif pool_config.protocol_version == (4, 1): # Carry out Bolt subclass imports locally to avoid circular dependency issues. from neo4j.io._bolt4x1 import Bolt4x1 connection = Bolt4x1(address, s, pool_config.max_connection_lifetime, auth=auth, user_agent=pool_config.user_agent) else: log.debug("[#%04X] S: <CLOSE>", s.getpeername()[1]) s.shutdown(SHUT_RDWR) s.close() supported_versions = Bolt.protocol_handlers().keys() raise BoltHandshakeError( "The Neo4J server does not support communication with this driver. This driver have support for Bolt Protocols {}" .format(supported_versions), address=address, request_data=handshake, response_data=data) connection.hello() return connection
async def open(cls, *addresses, auth=None, routing_context=None, loop=None, **config): pool_config = PoolConfig.consume(config) def opener(addr): return Bolt.open(addr, auth=auth, **pool_config) obj = cls(loop, opener, config, addresses, routing_context) await obj._ensure_routing_table_is_fresh() return obj
def test_pool_config_consume_key_not_valid(): test_config = dict(test_pool_config) test_config["not_valid_key"] = "test" with pytest.raises(ConfigurationError) as error: consumed_pool_config = PoolConfig.consume(test_config) error.match("Unexpected config keys: not_valid_key")
def open(cls, address, *, auth=None, **config): pool_config = PoolConfig.consume(config) def opener(addr, timeout): return Bolt.open(addr, auth=auth, timeout=timeout, **pool_config) pool = cls(opener, pool_config, address) seeds = [pool.acquire() for _ in range(pool_config.init_size)] pool.release(*seeds) return pool
def open(cls, address, *, auth=None, timeout=None, **config): """ Open a new Bolt connection to a given server address. :param address: :param auth: :param timeout: :param config: :return: """ config = PoolConfig.consume(config) return connect(address, auth=auth, timeout=timeout, config=config)
def test_pool_config_consume_default_values(): test_config = {} consumed_pool_config = PoolConfig.consume(test_config) assert isinstance(consumed_pool_config, PoolConfig) assert len(test_config) == 0 consumed_pool_config.keep_alive = "changed" assert PoolConfig.keep_alive != consumed_pool_config.keep_alive
async def open(cls, address, *, auth=None, loop=None, **config): """ Create a new connection pool, with an option to seed one or more initial connections. """ pool_config = PoolConfig.consume(config) def opener(addr): return Bolt.open(addr, auth=auth, loop=loop, **pool_config) pool = cls(loop, opener, pool_config, address) seeds = [await pool.acquire() for _ in range(pool_config.init_size)] for seed in seeds: await pool.release(seed) return pool
def open(cls, *addresses, auth=None, routing_context=None, **config): pool_config = PoolConfig.consume(config) def opener(addr, timeout): return Bolt.open(addr, auth=auth, timeout=timeout, **pool_config) pool = cls(opener, pool_config, addresses, routing_context) try: pool.update_routing_table() except Exception: pool.close() raise else: return pool
def ping(cls, address, *, timeout=None, **config): """ Attempt to establish a Bolt connection, returning the agreed Bolt protocol version if successful. """ config = PoolConfig.consume(config) try: s, protocol_version = connect(address, timeout=timeout, config=config) except ServiceUnavailable: return None else: s.close() return protocol_version
async def open(cls, address, *, auth=None, loop=None, **config): """ Open a socket connection and perform protocol version negotiation, in order to construct and return a Bolt client instance for a supported Bolt protocol version. :param address: tuples of host and port, such as ("127.0.0.1", 7687) :param auth: :param loop: :param config: :return: instance of a Bolt subclass :raise BoltConnectionError: if a connection could not be established :raise BoltConnectionLost: if an I/O error occurs on the underlying socket connection :raise BoltHandshakeError: if handshake completes without a successful negotiation :raise TypeError: if any of the arguments provided are passed as incompatible types :raise ValueError: if any of the arguments provided are passed with unsupported values """ # Args address = Address(address) if loop is None: loop = get_event_loop() config = PoolConfig.consume(config) # Connect reader, writer = await cls._connect(address, loop, config) try: # Handshake subclass = await cls._handshake(reader, writer, config.protocol_version) # Instantiation obj = subclass(reader, writer) obj.secure = bool(config.secure) assert hasattr(obj, "__ainit__") await obj.__ainit__(auth) return obj except BoltError: writer.write_eof() writer.close() raise
def __init__(self, unresolved_address, sock, *, auth=None, protocol_version=None, **config): self.config = PoolConfig.consume(config) self.protocol_version = protocol_version self.unresolved_address = unresolved_address self.socket = sock self.server = ServerInfo(Address(sock.getpeername()), protocol_version) self.outbox = Outbox() self.inbox = Inbox(BufferedSocket(self.socket, 32768), on_error=self._set_defunct) self.packer = Packer(self.outbox) self.unpacker = Unpacker(self.inbox) self.responses = deque() self._max_connection_lifetime = self.config.max_age self._creation_timestamp = perf_counter() # Determine the user agent user_agent = self.config.user_agent if user_agent: self.user_agent = user_agent else: self.user_agent = get_user_agent() # Determine auth details if not auth: self.auth_dict = {} elif isinstance(auth, tuple) and 2 <= len(auth) <= 3: from neo4j import Auth self.auth_dict = vars(Auth("basic", *auth)) else: try: self.auth_dict = vars(auth) except (KeyError, TypeError): raise AuthError("Cannot determine auth details from %r" % auth) # Check for missing password try: credentials = self.auth_dict["credentials"] except KeyError: pass else: if credentials is None: raise AuthError("Password cannot be None")
def open(cls, address, *, auth=None, timeout=None, **config): """ Open a new Bolt connection to a given server address. :param address: :param auth: :param timeout: :param config: :return: """ config = PoolConfig.consume(config) s, config.protocol_version = connect(address, timeout=timeout, config=config) connection = Bolt(address, s, auth=auth, **config) connection.hello() return connection
def test_pool_config_set_value(): test_config = dict(test_pool_config) consumed_pool_config = PoolConfig.consume(test_config) assert consumed_pool_config.get("encrypted") is False assert consumed_pool_config["encrypted"] is False assert consumed_pool_config.encrypted is False consumed_pool_config.encrypted = "test" assert consumed_pool_config.get("encrypted") == "test" assert consumed_pool_config["encrypted"] == "test" assert consumed_pool_config.encrypted == "test" consumed_pool_config.not_valid_key = "test" # Use consume functions
def ping(cls, address, *, timeout=None, **config): """ Attempt to establish a Bolt connection, returning the agreed Bolt protocol version if successful. """ config = PoolConfig.consume(config) try: s, protocol_version, handshake, data = connect( address, timeout=timeout, custom_resolver=config.resolver, ssl_context=config.get_ssl_context(), keep_alive=config.keep_alive, ) except (ServiceUnavailable, SessionExpired, BoltHandshakeError): return None else: _close_socket(s) return protocol_version
def _connect(resolved_address, timeout=None, **config): """ :param resolved_address: :param config: :return: socket object """ config = PoolConfig.consume(config) s = None try: if len(resolved_address) == 2: s = socket(AF_INET) elif len(resolved_address) == 4: s = socket(AF_INET6) else: raise ValueError("Unsupported address " "{!r}".format(resolved_address)) t = s.gettimeout() if timeout is None: s.settimeout(config.connect_timeout) else: s.settimeout(timeout) log.debug("[#0000] C: <OPEN> %s", resolved_address) s.connect(resolved_address) s.settimeout(t) keep_alive = 1 if config.keep_alive else 0 s.setsockopt(SOL_SOCKET, SO_KEEPALIVE, keep_alive) except SocketTimeout: log.debug("[#0000] C: <TIMEOUT> %s", resolved_address) log.debug("[#0000] C: <CLOSE> %s", resolved_address) s.close() raise ServiceUnavailable("Timed out trying to establish connection " "to {!r}".format(resolved_address)) except OSError as error: log.debug("[#0000] C: <ERROR> %s %s", type(error).__name__, " ".join(map(repr, error.args))) log.debug("[#0000] C: <CLOSE> %s", resolved_address) s.close() raise ServiceUnavailable("Failed to establish connection to {!r} " "(reason {})".format(resolved_address, error)) else: return s
def test_pool_config_consume(): test_config = dict(test_pool_config) consumed_pool_config = PoolConfig.consume(test_config) assert isinstance(consumed_pool_config, PoolConfig) assert len(test_config) == 0 for key in test_pool_config.keys(): assert consumed_pool_config[key] == test_pool_config[key] for key in consumed_pool_config.keys(): if key not in config_function_names: assert test_pool_config[key] == consumed_pool_config[key] assert len(consumed_pool_config) - len(config_function_names) == len( test_pool_config)