def _create_transport(index, transport, check_native_endpoint=None): """ Internal helper to insert defaults and create _Transport instances. :param transport: a (possibly valid) transport configuration :type transport: dict :returns: a _Transport instance :raises: ValueError on invalid configuration """ if type(transport) != dict: raise ValueError( 'invalid type {} for transport configuration - must be a dict'. format(type(transport))) valid_transport_keys = [ 'type', 'url', 'endpoint', 'serializer', 'serializers', 'options', 'max_retries', 'max_retry_delay', 'initial_retry_delay', 'retry_delay_growth', 'retry_delay_jitter', ] for k in transport.keys(): if k not in valid_transport_keys: raise ValueError( "'{}' is not a valid configuration item".format(k)) kind = 'websocket' if 'type' in transport: if transport['type'] not in ['websocket', 'rawsocket']: raise ValueError('Invalid transport type {}'.format( transport['type'])) kind = transport['type'] else: transport['type'] = 'websocket' options = dict() if 'options' in transport: options = transport['options'] if not isinstance(options, dict): raise ValueError('options must be a dict, not {}'.format( type(options))) if kind == 'websocket': for key in ['url']: if key not in transport: raise ValueError("Transport requires '{}' key".format(key)) # endpoint not required; we will deduce from URL if it's not provided # XXX not in the branch I rebased; can this go away? (is it redundant??) if 'endpoint' not in transport: is_secure, host, port, resource, path, params = parse_ws_url( transport['url']) endpoint_config = { 'type': 'tcp', 'host': host, 'port': port, 'tls': is_secure, } else: # note: we're avoiding mutating the incoming "configuration" # dict, so this should avoid that too... endpoint_config = transport['endpoint'] _validate_endpoint(endpoint_config, check_native_endpoint) if 'serializer' in transport: raise ValueError( "'serializer' is only for rawsocket; use 'serializers'") if 'serializers' in transport: if not isinstance(transport['serializers'], (list, tuple)): raise ValueError("'serializers' must be a list of strings") if not all([ isinstance(s, (six.text_type, str)) for s in transport['serializers'] ]): raise ValueError("'serializers' must be a list of strings") valid_serializers = SERID_TO_SER.keys() for serial in transport['serializers']: if serial not in valid_serializers: raise ValueError( "Invalid serializer '{}' (expected one of: {})".format( serial, ', '.join([repr(s) for s in valid_serializers]), )) serializer_config = transport.get('serializers', [u'cbor', u'json']) elif kind == 'rawsocket': if 'endpoint' not in transport: if transport['url'].startswith('rs'): # # try to parse RawSocket URL .. isSecure, host, port = parse_rs_url(transport['url']) elif transport['url'].startswith('ws'): # try to parse WebSocket URL .. isSecure, host, port, resource, path, params = parse_ws_url( transport['url']) else: raise RuntimeError() if host == 'unix': # here, "port" is actually holding the path on the host, eg "/tmp/file.sock" endpoint_config = { 'type': 'unix', 'path': port, } else: endpoint_config = { 'type': 'tcp', 'host': host, 'port': port, } else: endpoint_config = transport['endpoint'] if 'serializers' in transport: raise ValueError( "'serializers' is only for websocket; use 'serializer'") # always a list; len == 1 for rawsocket if 'serializer' in transport: if not isinstance(transport['serializer'], (six.text_type, str)): raise ValueError("'serializer' must be a string") serializer_config = [transport['serializer']] else: serializer_config = [u'cbor'] else: assert False, 'should not arrive here' kw = {} for key in [ 'max_retries', 'max_retry_delay', 'initial_retry_delay', 'retry_delay_growth', 'retry_delay_jitter' ]: if key in transport: kw[key] = transport[key] return _Transport(index, kind=kind, url=transport['url'], endpoint=endpoint_config, serializers=serializer_config, options=options, **kw)
def _create_transport(index, transport, check_native_endpoint=None): """ Internal helper to insert defaults and create _Transport instances. :param transport: a (possibly valid) transport configuration :type transport: dict :returns: a _Transport instance :raises: ValueError on invalid configuration """ if type(transport) != dict: raise ValueError('invalid type {} for transport configuration - must be a dict'.format(type(transport))) valid_transport_keys = [ 'type', 'url', 'endpoint', 'serializer', 'serializers', 'options', 'max_retries', 'max_retry_delay', 'initial_retry_delay', 'retry_delay_growth', 'retry_delay_jitter', 'proxy', ] for k in transport.keys(): if k not in valid_transport_keys: raise ValueError( "'{}' is not a valid configuration item".format(k) ) kind = 'websocket' if 'type' in transport: if transport['type'] not in ['websocket', 'rawsocket']: raise ValueError('Invalid transport type {}'.format(transport['type'])) kind = transport['type'] else: transport['type'] = 'websocket' if 'proxy' in transport and kind != 'websocket': raise ValueError( "proxy= only supported for type=websocket transports" ) proxy = transport.get("proxy", None) if proxy is not None: for k in proxy.keys(): if k not in ['host', 'port']: raise ValueError( "Unknown key '{}' in proxy config".format(k) ) for k in ['host', 'port']: if k not in proxy: raise ValueError( "Proxy config requires '{}'".formaT(k) ) options = dict() if 'options' in transport: options = transport['options'] if not isinstance(options, dict): raise ValueError( 'options must be a dict, not {}'.format(type(options)) ) if kind == 'websocket': for key in ['url']: if key not in transport: raise ValueError("Transport requires '{}' key".format(key)) # endpoint not required; we will deduce from URL if it's not provided # XXX not in the branch I rebased; can this go away? (is it redundant??) if 'endpoint' not in transport: is_secure, host, port, resource, path, params = parse_ws_url(transport['url']) endpoint_config = { 'type': 'tcp', 'host': host, 'port': port, 'tls': is_secure, } else: # note: we're avoiding mutating the incoming "configuration" # dict, so this should avoid that too... endpoint_config = transport['endpoint'] _validate_endpoint(endpoint_config, check_native_endpoint) if 'serializer' in transport: raise ValueError("'serializer' is only for rawsocket; use 'serializers'") if 'serializers' in transport: if not isinstance(transport['serializers'], (list, tuple)): raise ValueError("'serializers' must be a list of strings") if not all([ isinstance(s, (six.text_type, str)) for s in transport['serializers']]): raise ValueError("'serializers' must be a list of strings") valid_serializers = SERID_TO_SER.keys() for serial in transport['serializers']: if serial not in valid_serializers: raise ValueError( "Invalid serializer '{}' (expected one of: {})".format( serial, ', '.join([repr(s) for s in valid_serializers]), ) ) serializer_config = transport.get('serializers', [u'cbor', u'json']) elif kind == 'rawsocket': if 'endpoint' not in transport: if transport['url'].startswith('rs'): # # try to parse RawSocket URL .. isSecure, host, port = parse_rs_url(transport['url']) elif transport['url'].startswith('ws'): # try to parse WebSocket URL .. isSecure, host, port, resource, path, params = parse_ws_url(transport['url']) else: raise RuntimeError() if host == 'unix': # here, "port" is actually holding the path on the host, eg "/tmp/file.sock" endpoint_config = { 'type': 'unix', 'path': port, } else: endpoint_config = { 'type': 'tcp', 'host': host, 'port': port, } else: endpoint_config = transport['endpoint'] if 'serializers' in transport: raise ValueError("'serializers' is only for websocket; use 'serializer'") # always a list; len == 1 for rawsocket if 'serializer' in transport: if not isinstance(transport['serializer'], (six.text_type, str)): raise ValueError("'serializer' must be a string") serializer_config = [transport['serializer']] else: serializer_config = [u'cbor'] else: assert False, 'should not arrive here' kw = {} for key in ['max_retries', 'max_retry_delay', 'initial_retry_delay', 'retry_delay_growth', 'retry_delay_jitter']: if key in transport: kw[key] = transport[key] return _Transport( index, kind=kind, url=transport.get('url', None), endpoint=endpoint_config, serializers=serializer_config, proxy=proxy, options=options, **kw )