@@ -36,8 +36,8 @@ def __init__(self, base_url=None, creds=None):
3636 _base_client_models = {k : v for k , v in _models .__dict__ .items () if isinstance (v , type )}
3737 self ._base_deserialize = Deserializer (_base_client_models )
3838 self ._base_serialize = Serializer (_base_client_models )
39- self ._all_host_types_locations = None
40- self ._locations = None
39+ self ._all_host_types_locations = {}
40+ self ._locations = {}
4141 self ._suppress_fedauth_redirect = True
4242 self ._force_msa_pass_through = True
4343 self .normalized_url = Client ._normalize_url (base_url )
@@ -76,7 +76,7 @@ def _send(self, http_method, location_id, version, route_values=None,
7676 route_values = route_values ,
7777 query_parameters = query_parameters )
7878 negotiated_version = self ._negotiate_request_version (
79- self ._get_resource_location (location_id ),
79+ self ._get_resource_location (self . normalized_url , location_id ),
8080 version )
8181
8282 if version != negotiated_version :
@@ -116,19 +116,31 @@ def _unwrap_collection(self, response):
116116
117117 def _create_request_message (self , http_method , location_id , route_values = None ,
118118 query_parameters = None ):
119- location = self ._get_resource_location (location_id )
119+ location = self ._get_organization_resource_location (location_id )
120+ deployment_level = False
121+ deployment_url = None
120122 if location is None :
121- raise ValueError ('API resource location ' + location_id + ' is not registered on '
122- + self .config .base_url + '.' )
123+ logger .debug ('API resource location ' + location_id + ' is not registered on ' + self .config .base_url + '.' )
124+ deployment_url = self ._get_deployment_url ()
125+ if deployment_url is not None :
126+ logger .debug ('Checking for location at deployment level: ' + deployment_url )
127+ location = self ._get_resource_location (deployment_url , location_id )
128+ deployment_level = True
129+ if location is None :
130+ raise ValueError ('API resource location ' + location_id + ' is not registered on '
131+ + self .config .base_url + '.' )
123132 if route_values is None :
124133 route_values = {}
125134 route_values ['area' ] = location .area
126135 route_values ['resource' ] = location .resource_name
127136 route_template = self ._remove_optional_route_parameters (location .route_template ,
128137 route_values )
129138 logger .debug ('Route template: %s' , location .route_template )
130- url = self ._client .format_url (route_template , ** route_values )
131- request = ClientRequest (method = http_method , url = self ._client .format_url (url ))
139+ if not deployment_level :
140+ url = self ._client .format_url (route_template , ** route_values )
141+ else :
142+ url = self ._client .format_url (deployment_url + route_template , ** route_values )
143+ request = ClientRequest (method = http_method , url = url )
132144 if query_parameters :
133145 request .format_parameters (query_parameters )
134146 return request
@@ -144,35 +156,46 @@ def _remove_optional_route_parameters(route_template, route_values):
144156 new_template = new_template + '/' + path_segment
145157 return new_template
146158
147- def _get_resource_location (self , location_id ):
148- if self .config .base_url not in Client ._locations_cache :
149- Client ._locations_cache [self .config .base_url ] = self ._get_resource_locations (all_host_types = False )
150- for location in Client ._locations_cache [self .config .base_url ]:
159+ def _get_organization_resource_location (self , location_id ):
160+ return self ._get_resource_location (self .normalized_url , location_id )
161+
162+ def _get_deployment_url (self ):
163+ pos = self .normalized_url .rfind ('/' )
164+ if pos > 0 :
165+ deployment_url = self .normalized_url [:pos ]
166+ if deployment_url .find ('://' ) > 0 :
167+ return deployment_url
168+ return None
169+
170+ def _get_resource_location (self , url , location_id ):
171+ if url not in Client ._locations_cache :
172+ Client ._locations_cache [url ] = self ._get_resource_locations (url , all_host_types = False )
173+ for location in Client ._locations_cache [url ]:
151174 if location .id == location_id :
152175 return location
153176
154- def _get_resource_locations (self , all_host_types ):
177+ def _get_resource_locations (self , url , all_host_types ):
155178 # Check local client's cached Options first
156179 if all_host_types :
157- if self ._all_host_types_locations is not None :
158- return self ._all_host_types_locations
159- elif self ._locations is not None :
160- return self ._locations
180+ if url in self ._all_host_types_locations :
181+ return self ._all_host_types_locations [ url ]
182+ elif url in self ._locations :
183+ return self ._locations [ url ]
161184
162185 # Next check for options cached on disk
163- if not all_host_types and OPTIONS_FILE_CACHE [self . normalized_url ]:
186+ if not all_host_types and OPTIONS_FILE_CACHE [url ]:
164187 try :
165- logger .debug ('File cache hit for options on: %s' , self . normalized_url )
166- self ._locations = self ._base_deserialize .deserialize_data (OPTIONS_FILE_CACHE [self . normalized_url ],
188+ logger .debug ('File cache hit for options on: %s' , url )
189+ self ._locations [ url ] = self ._base_deserialize .deserialize_data (OPTIONS_FILE_CACHE [url ],
167190 '[ApiResourceLocation]' )
168- return self ._locations
191+ return self ._locations [ url ]
169192 except DeserializationError as ex :
170193 logger .debug (ex , exc_info = True )
171194 else :
172- logger .debug ('File cache miss for options on: %s' , self . normalized_url )
195+ logger .debug ('File cache miss for options on: %s' , url )
173196
174197 # Last resort, make the call to the server
175- options_uri = self ._combine_url (self . config . base_url , '_apis' )
198+ options_uri = self ._combine_url (url , '_apis' )
176199 request = ClientRequest (method = 'OPTIONS' , url = self ._client .format_url (options_uri ))
177200 if all_host_types :
178201 query_parameters = {'allHostTypes' : True }
@@ -190,11 +213,11 @@ def _get_resource_locations(self, all_host_types):
190213 returned_locations = self ._base_deserialize ('[ApiResourceLocation]' ,
191214 collection )
192215 if all_host_types :
193- self ._all_host_types_locations = returned_locations
216+ self ._all_host_types_locations [ url ] = returned_locations
194217 else :
195- self ._locations = returned_locations
218+ self ._locations [ url ] = returned_locations
196219 try :
197- OPTIONS_FILE_CACHE [self . normalized_url ] = wrapper .value
220+ OPTIONS_FILE_CACHE [url ] = wrapper .value
198221 except SerializationError as ex :
199222 logger .debug (ex , exc_info = True )
200223 return returned_locations
0 commit comments