44import re
55from base64 import b64encode , b64decode
66
7- APERTURE_CLOUD = ".cloud.aperturedata.io"
8- AD_CLOUD_SCHEME = "adbc://"
7+ APERTUREDB_CLOUD = ".cloud.aperturedata.io"
8+ APERTUREDB_KEY_VERSION = 1
9+ FLAG_USE_COMPRESSED_HOST = 4
10+ FLAG_USE_REST = 2
11+ FLAG_USE_SSL = 1
12+ DEFAULT_HTTP_PORT = 80
13+ DEFAULT_HTTPS_PORT = 443
14+ DEFAULT_TCP_PORT = 55555
915
1016
1117@dataclass (repr = False )
@@ -34,16 +40,8 @@ def __repr__(self) -> str:
3440 return f"[{ self .host } :{ self .port } as { self .username } using { mode } with SSL={ self .use_ssl } auth={ auth_mode } ]"
3541
3642 def deflate (self ) -> list :
37- deflate_version = 1
38- host = self .host
39- if host .endswith (APERTURE_CLOUD ):
40- host = "adbc://{}" .format (host [:- 1 * len (APERTURE_CLOUD )])
41- as_list = [deflate_version , host , self .port , self .username , self .password , self .name , int (self .use_ssl ),
42- int (self .use_rest ), int (self .use_keepalive ),
43- self .retry_interval_seconds , self .retry_max_attempts ]
44- simplified = json .dumps (as_list )
45- encoded_key = b64encode (simplified .encode ('utf-8' )).decode ('utf-8' )
46- return encoded_key
43+ return self .create_aperturedb_key (self .host , self .port , self .token ,
44+ self .use_rest , self .use_ssl , self .username , self .password )
4745
4846 def has_user_keys (self ) -> bool :
4947 return self .user_keys is not None
@@ -65,76 +63,90 @@ def set_user_keys(self, keys: dict) -> None:
6563 self .user_keys = keys
6664
6765 @classmethod
68- def create_web_token (cls , host : str , port : int , token_string : str ) -> None :
69- if token_string .startswith ("adbp_" ):
66+ def config_to_key_type (cls , compressed_host : bool , use_rest : bool , use_ssl : bool ):
67+ return (FLAG_USE_COMPRESSED_HOST if compressed_host else 0 ) + \
68+ (FLAG_USE_REST if use_rest else 0 ) + \
69+ (FLAG_USE_SSL if use_ssl else 0 )
70+
71+ @classmethod
72+ def key_type_to_config (cls , key_type : int ): \
73+ return [bool (key_type & FLAG_USE_COMPRESSED_HOST ),
74+ bool (key_type & FLAG_USE_REST ),
75+ bool (key_type & FLAG_USE_SSL )]
76+
77+ @classmethod
78+ def config_default_port (cls , use_rest : bool , use_ssl : bool ):
79+ if use_rest :
80+ return DEFAULT_HTTPS_PORT if use_ssl else DEFAULT_HTTP_PORT
81+ else :
82+ return DEFAULT_TCP_PORT
83+
84+ @classmethod
85+ def create_aperturedb_key (cls , host : str , port : int , token_string : str ,
86+ use_rest : bool , use_ssl : bool , username : str = None , password : str = None ) -> None :
87+ compressed = False
88+ if token_string is not None and token_string .startswith ("adbp_" ):
7089 token_string = token_string [5 :]
7190
72- if host .endswith (APERTURE_CLOUD ):
73- host = host [:- 1 * len (APERTURE_CLOUD )]
91+ if host .endswith (APERTUREDB_CLOUD ):
92+ host = host [:- 1 * len (APERTUREDB_CLOUD )]
7493 m = re .match ("(.*)\.farm(\d+)$" , host )
7594 if m is not None :
7695 host = "{}.{}" .format (m .group (1 ), int (m .group (2 )))
77-
78- host = "a://{}" .format (host )
79-
80- if port == 55555 :
81- web_token_json = [2 , host , token_string ]
96+ compressed = True
97+
98+ key_type = cls .config_to_key_type (compressed , use_rest , use_ssl )
99+ default_port = cls .config_default_port (use_rest , use_ssl )
100+ if port != default_port :
101+ host = f"{ host } :{ port } "
102+ if token_string is not None :
103+ key_json = [APERTUREDB_KEY_VERSION , key_type , host , token_string ]
82104 else :
83- web_token_json = [2 , host , port , token_string ]
84- simplified = json .dumps (web_token_json )
105+ key_json = [APERTUREDB_KEY_VERSION ,
106+ key_type , host , username , password ]
107+ simplified = json .dumps (key_json , separators = (',' , ':' ))
85108 encoded = b64encode (simplified .encode ('utf-8' )).decode ('utf-8' )
86109 return encoded
87110
88111 @classmethod
89112 def reinflate (cls , encoded_str : list ) -> object :
113+ name = "default_key"
90114 try :
91115 decoded = b64decode (encoded_str .encode ('utf-8' ))
92116 as_list = json .loads (decoded .decode ('utf-8' ))
93117 except :
94118 raise Exception (
95119 "Unable to make configuration from the provided string" )
96120 version = as_list [0 ]
97- if version not in (1 , 2 ):
121+ if version not in (APERTUREDB_KEY_VERSION , ):
98122 raise ValueError ("version identifier of configuration was"
99- f"g{ as_list [0 ]} , which is not supported" )
100- if version == 1 :
101- host , port , username , password , name , use_ssl , \
102- use_rest , use_keepalive , retry_interval_seconds , \
103- retry_max_attempts = as_list [1 :]
104- if host .startswith (AD_CLOUD_SCHEME ):
105- host = host [len (AD_CLOUD_SCHEME ):] + APERTURE_CLOUD
106- use_ssl = bool (use_ssl )
107- use_rest = bool (use_rest )
108- use_keepaliave = bool (use_keepalive )
109- c = Configuration (
110- host , port , username , password , name , use_ssl , use_rest , use_keepalive ,
111- retry_interval_seconds , retry_max_attempts )
112- elif version == 2 :
113- host = as_list [1 ]
114- if host .startswith ("a://" ):
115- m = re .match ("a://([^.]*)\.(\d+)" , host )
116- host = "{}.farm{:04d}.cloud.aperturedata.io" .format (
117- m .group (1 ), int (m .group (2 )))
118-
119- cur_arg = 2
120- # second arg is port
121- if isinstance (as_list [2 ], int ):
122- cur_arg = 3
123- else :
124- port = 55555
125-
126- name = "default"
127-
128- username = None
129- password = None
130- token = None
131- # if 1 argument left, treat as token.
132- if len (as_list ) - cur_arg == 1 :
133- token = "adbp_" + as_list [cur_arg ]
134- else :
135- username = as_list [cur_arg ]
136- password = as_list [cur_arg + 1 ]
137-
138- c = Configuration (host , port , username ,
139- password , name , token = token )
123+ f"{ version } , which is not supported" )
124+ is_compressed , use_rest , use_ssl = cls .key_type_to_config (as_list [1 ])
125+ host = as_list [2 ]
126+ token = username = password = None
127+ if len (as_list ) == 4 :
128+ token = "adbp_" + as_list [3 ]
129+ elif len (as_list ) == 5 :
130+ username , password = as_list [3 :]
131+
132+ port_match = re .match (".*:(\d+)$" , host )
133+ if port_match is not None :
134+ port = int (port_match .group (1 ))
135+ host = host [:- 1 * (len (port_match .group (1 )) + 1 )]
136+ else :
137+ port = cls .config_default_port (use_rest , use_ssl )
138+
139+ if is_compressed :
140+ try :
141+ first , second = host .split ('.' )
142+ host = "{}.farm{:04d}{}" .format (
143+ first , int (second ), APERTUREDB_CLOUD )
144+ except Exception as e :
145+ raise ValueError (
146+ f"Unable to parse compressed host: { host } Error: { e } " )
147+
148+ c = Configuration (
149+ host , port , username , password , name , use_ssl , use_rest )
150+ if token :
151+ c .token = token
140152 return c
0 commit comments