@@ -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,44 @@ 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+ return self .normalized_url [:pos ]
166+ return None
167+
168+ def _get_resource_location (self , url , location_id ):
169+ if url not in Client ._locations_cache :
170+ Client ._locations_cache [url ] = self ._get_resource_locations (url , all_host_types = False )
171+ for location in Client ._locations_cache [url ]:
151172 if location .id == location_id :
152173 return location
153174
154- def _get_resource_locations (self , all_host_types ):
175+ def _get_resource_locations (self , url , all_host_types ):
155176 # Check local client's cached Options first
156177 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
178+ if url in self ._all_host_types_locations :
179+ return self ._all_host_types_locations [ url ]
180+ elif url in self ._locations :
181+ return self ._locations [ url ]
161182
162183 # Next check for options cached on disk
163- if not all_host_types and OPTIONS_FILE_CACHE [self . normalized_url ]:
184+ if not all_host_types and OPTIONS_FILE_CACHE [url ]:
164185 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 ],
186+ logger .debug ('File cache hit for options on: %s' , url )
187+ self ._locations [ url ] = self ._base_deserialize .deserialize_data (OPTIONS_FILE_CACHE [url ],
167188 '[ApiResourceLocation]' )
168- return self ._locations
189+ return self ._locations [ url ]
169190 except DeserializationError as ex :
170191 logger .debug (ex , exc_info = True )
171192 else :
172- logger .debug ('File cache miss for options on: %s' , self . normalized_url )
193+ logger .debug ('File cache miss for options on: %s' , url )
173194
174195 # Last resort, make the call to the server
175- options_uri = self ._combine_url (self . config . base_url , '_apis' )
196+ options_uri = self ._combine_url (url , '_apis' )
176197 request = ClientRequest (method = 'OPTIONS' , url = self ._client .format_url (options_uri ))
177198 if all_host_types :
178199 query_parameters = {'allHostTypes' : True }
@@ -190,11 +211,11 @@ def _get_resource_locations(self, all_host_types):
190211 returned_locations = self ._base_deserialize ('[ApiResourceLocation]' ,
191212 collection )
192213 if all_host_types :
193- self ._all_host_types_locations = returned_locations
214+ self ._all_host_types_locations [ url ] = returned_locations
194215 else :
195- self ._locations = returned_locations
216+ self ._locations [ url ] = returned_locations
196217 try :
197- OPTIONS_FILE_CACHE [self . normalized_url ] = wrapper .value
218+ OPTIONS_FILE_CACHE [url ] = wrapper .value
198219 except SerializationError as ex :
199220 logger .debug (ex , exc_info = True )
200221 return returned_locations
0 commit comments