<s> """<STR_LIT>""" <EOL> import base64 <EOL> import json <EOL> import logging <EOL> import re <EOL> import threading <EOL> from google . appengine . tools . devappserver2 . endpoints import discovery_service <EOL> _API_REST_PATH_FORMAT = '<STR_LIT>' <EOL> _PATH_VARIABLE_PATTERN = r'<STR_LIT>' <EOL> _RESERVED_PATH_VARIABLE_PATTERN = r'<STR_LIT:!>' + _PATH_VARIABLE_PATTERN <EOL> _PATH_VALUE_PATTERN = r'<STR_LIT>' <EOL> class ApiConfigManager ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . _rpc_method_dict = { } <EOL> self . _rest_methods = [ ] <EOL> self . configs = { } <EOL> self . _config_lock = threading . Lock ( ) <EOL> def _convert_https_to_http ( self , config ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT>' in config and '<STR_LIT>' in config [ '<STR_LIT>' ] : <EOL> bns_adapter = config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> if bns_adapter . startswith ( '<STR_LIT>' ) : <EOL> config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = bns_adapter . replace ( '<STR_LIT>' , '<STR_LIT:http>' , <NUM_LIT:1> ) <EOL> if '<STR_LIT:root>' in config and config [ '<STR_LIT:root>' ] . startswith ( '<STR_LIT>' ) : <EOL> config [ '<STR_LIT:root>' ] = config [ '<STR_LIT:root>' ] . replace ( '<STR_LIT>' , '<STR_LIT:http>' , <NUM_LIT:1> ) <EOL> def parse_api_config_response ( self , body ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> response_obj = json . loads ( body ) <EOL> except ValueError , unused_err : <EOL> logging . error ( '<STR_LIT>' , <EOL> body ) <EOL> else : <EOL> with self . _config_lock : <EOL> self . _add_discovery_config ( ) <EOL> for api_config_json in response_obj . get ( '<STR_LIT>' , [ ] ) : <EOL> try : <EOL> config = json . loads ( api_config_json ) <EOL> except ValueError , unused_err : <EOL> logging . error ( '<STR_LIT>' , <EOL> api_config_json ) <EOL> else : <EOL> lookup_key = config . get ( '<STR_LIT:name>' , '<STR_LIT>' ) , config . get ( '<STR_LIT:version>' , '<STR_LIT>' ) <EOL> self . _convert_https_to_http ( config ) <EOL> self . configs [ lookup_key ] = config <EOL> for config in self . configs . itervalues ( ) : <EOL> version = config . get ( '<STR_LIT:version>' , '<STR_LIT>' ) <EOL> sorted_methods = self . _get_sorted_methods ( config . get ( '<STR_LIT>' , { } ) ) <EOL> for method_name , method in sorted_methods : <EOL> self . _save_rpc_method ( method_name , version , method ) <EOL> self . _save_rest_method ( method_name , version , method ) <EOL> def _get_sorted_methods ( self , methods ) : <EOL> """<STR_LIT>""" <EOL> if not methods : <EOL> return methods <EOL> def _sorted_methods_comparison ( method_info1 , method_info2 ) : <EOL> """<STR_LIT>""" <EOL> def _score_path ( path ) : <EOL> """<STR_LIT>""" <EOL> score = <NUM_LIT:0> <EOL> parts = path . split ( '<STR_LIT:/>' ) <EOL> for part in parts : <EOL> score <<= <NUM_LIT:1> <EOL> if not part or part [ <NUM_LIT:0> ] != '<STR_LIT:{>' : <EOL> score += <NUM_LIT:1> <EOL> score <<= <NUM_LIT> - len ( parts ) <EOL> return score <EOL> path_score1 = _score_path ( method_info1 [ <NUM_LIT:1> ] . get ( '<STR_LIT:path>' , '<STR_LIT>' ) ) <EOL> path_score2 = _score_path ( method_info2 [ <NUM_LIT:1> ] . get ( '<STR_LIT:path>' , '<STR_LIT>' ) ) <EOL> if path_score1 != path_score2 : <EOL> return path_score2 - path_score1 <EOL> path_result = cmp ( method_info1 [ <NUM_LIT:1> ] . get ( '<STR_LIT:path>' , '<STR_LIT>' ) , <EOL> method_info2 [ <NUM_LIT:1> ] . get ( '<STR_LIT:path>' , '<STR_LIT>' ) ) <EOL> if path_result != <NUM_LIT:0> : <EOL> return path_result <EOL> method_result = cmp ( method_info1 [ <NUM_LIT:1> ] . get ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> method_info2 [ <NUM_LIT:1> ] . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> return method_result <EOL> return sorted ( methods . items ( ) , _sorted_methods_comparison ) <EOL> @ staticmethod <EOL> def _get_path_params ( match ) : <EOL> """<STR_LIT>""" <EOL> result = { } <EOL> for var_name , value in match . groupdict ( ) . iteritems ( ) : <EOL> actual_var_name = ApiConfigManager . _from_safe_path_param_name ( var_name ) <EOL> result [ actual_var_name ] = value <EOL> return result <EOL> def lookup_rpc_method ( self , method_name , version ) : <EOL> """<STR_LIT>""" <EOL> with self . _config_lock : <EOL> method = self . _rpc_method_dict . get ( ( method_name , version ) ) <EOL> return method <EOL> def lookup_rest_method ( self , path , http_method ) : <EOL> """<STR_LIT>""" <EOL> with self . _config_lock : <EOL> for compiled_path_pattern , unused_path , methods in self . _rest_methods : <EOL> match = compiled_path_pattern . match ( path ) <EOL> if match : <EOL> params = self . _get_path_params ( match ) <EOL> version = match . group ( <NUM_LIT:2> ) <EOL> method_key = ( http_method . lower ( ) , version ) <EOL> method_name , method = methods . get ( method_key , ( None , None ) ) <EOL> if method : <EOL> break <EOL> else : <EOL> logging . warn ( '<STR_LIT>' , path ) <EOL> method_name = None <EOL> method = None <EOL> params = None <EOL> return method_name , method , params <EOL> def _add_discovery_config ( self ) : <EOL> lookup_key = ( discovery_service . DiscoveryService . API_CONFIG [ '<STR_LIT:name>' ] , <EOL> discovery_service . DiscoveryService . API_CONFIG [ '<STR_LIT:version>' ] ) <EOL> self . configs [ lookup_key ] = discovery_service . DiscoveryService . API_CONFIG <EOL> @ staticmethod <EOL> def _to_safe_path_param_name ( matched_parameter ) : <EOL> """<STR_LIT>""" <EOL> return '<STR_LIT:_>' + base64 . b32encode ( matched_parameter ) . rstrip ( '<STR_LIT:=>' ) <EOL> @ staticmethod <EOL> def _from_safe_path_param_name ( safe_parameter ) : <EOL> """<STR_LIT>""" <EOL> assert safe_parameter . startswith ( '<STR_LIT:_>' ) <EOL> safe_parameter_as_base32 = safe_parameter [ <NUM_LIT:1> : ] <EOL> padding_length = - len ( safe_parameter_as_base32 ) % <NUM_LIT:8> <EOL> padding = '<STR_LIT:=>' * padding_length <EOL> return base64 . b32decode ( safe_parameter_as_base32 + padding ) <EOL> @ staticmethod <EOL> def _compile_path_pattern ( pattern ) : <EOL> r"""<STR_LIT>""" <EOL> def replace_reserved_variable ( match ) : <EOL> """<STR_LIT>""" <EOL> if match . lastindex > <NUM_LIT:1> : <EOL> return '<STR_LIT>' % ( match . group ( <NUM_LIT:1> ) , _PATH_VALUE_PATTERN ) <EOL> return match . group ( <NUM_LIT:0> ) <EOL> def replace_variable ( match ) : <EOL> """<STR_LIT>""" <EOL> if match . lastindex > <NUM_LIT:1> : <EOL> var_name = ApiConfigManager . _to_safe_path_param_name ( match . group ( <NUM_LIT:2> ) ) <EOL> return '<STR_LIT>' % ( match . group ( <NUM_LIT:1> ) , var_name , <EOL> _PATH_VALUE_PATTERN ) <EOL> return match . group ( <NUM_LIT:0> ) <EOL> pattern = re . sub ( '<STR_LIT>' % _RESERVED_PATH_VARIABLE_PATTERN , <EOL> replace_reserved_variable , pattern , <NUM_LIT:2> ) <EOL> pattern = re . sub ( '<STR_LIT>' % _PATH_VARIABLE_PATTERN , <EOL> replace_variable , pattern ) <EOL> return re . compile ( pattern + '<STR_LIT>' ) <EOL> def _save_rpc_method ( self , method_name , version , method ) : <EOL> """<STR_LIT>""" <EOL> self . _rpc_method_dict [ ( method_name , version ) ] = method <EOL> def _save_rest_method ( self , method_name , version , method ) : <EOL> """<STR_LIT>""" <EOL> path_pattern = _API_REST_PATH_FORMAT % method . get ( '<STR_LIT:path>' , '<STR_LIT>' ) <EOL> http_method = method . get ( '<STR_LIT>' , '<STR_LIT>' ) . lower ( ) <EOL> for _ , path , methods in self . _rest_methods : <EOL> if path == path_pattern : <EOL> methods [ ( http_method , version ) ] = method_name , method <EOL> break <EOL> else : <EOL> self . _rest_methods . append ( <EOL> ( self . _compile_path_pattern ( path_pattern ) , <EOL> path_pattern , <EOL> { ( http_method , version ) : ( method_name , method ) } ) ) </s>
