@@ -66,7 +66,6 @@ def list(self, request):
6666import logging
6767import os
6868
69- from . import api_backend_service
7069from . import api_config
7170from . import api_exceptions
7271from . import endpoints_dispatcher
@@ -76,6 +75,7 @@ def list(self, request):
7675from endpoints_management .control import client as control_client
7776from endpoints_management .control import wsgi as control_wsgi
7877
78+ from protorpc import message_types
7979from protorpc import messages
8080from protorpc import remote
8181from protorpc .wsgi import service as wsgi_service
@@ -88,6 +88,7 @@ def list(self, request):
8888
8989
9090__all__ = [
91+ 'ApiConfigRegistry' ,
9192 'api_server' ,
9293 'EndpointsErrorMessage' ,
9394 'package' ,
@@ -183,6 +184,90 @@ def _get_app_revision(environ=None):
183184 return environ ['CURRENT_VERSION_ID' ].split ('.' )[1 ]
184185
185186
187+ class ApiConfigRegistry (object ):
188+ """Registry of active APIs"""
189+
190+ def __init__ (self ):
191+ # Set of API classes that have been registered.
192+ self .__registered_classes = set ()
193+ # Set of API config contents served by this App Engine AppId/version
194+ self .__api_configs = []
195+ # Map of API method name to ProtoRPC method name.
196+ self .__api_methods = {}
197+
198+ # pylint: disable=g-bad-name
199+ def register_backend (self , config_contents ):
200+ """Register a single API and its config contents.
201+
202+ Args:
203+ config_contents: Dict containing API configuration.
204+ """
205+ if config_contents is None :
206+ return
207+ self .__register_class (config_contents )
208+ self .__api_configs .append (config_contents )
209+ self .__register_methods (config_contents )
210+
211+ def __register_class (self , parsed_config ):
212+ """Register the class implementing this config, so we only add it once.
213+
214+ Args:
215+ parsed_config: The JSON object with the API configuration being added.
216+
217+ Raises:
218+ ApiConfigurationError: If the class has already been registered.
219+ """
220+ methods = parsed_config .get ('methods' )
221+ if not methods :
222+ return
223+
224+ # Determine the name of the class that implements this configuration.
225+ service_classes = set ()
226+ for method in methods .itervalues ():
227+ rosy_method = method .get ('rosyMethod' )
228+ if rosy_method and '.' in rosy_method :
229+ method_class = rosy_method .split ('.' , 1 )[0 ]
230+ service_classes .add (method_class )
231+
232+ for service_class in service_classes :
233+ if service_class in self .__registered_classes :
234+ raise api_exceptions .ApiConfigurationError (
235+ 'API class %s has already been registered.' % service_class )
236+ self .__registered_classes .add (service_class )
237+
238+ def __register_methods (self , parsed_config ):
239+ """Register all methods from the given api config file.
240+
241+ Methods are stored in a map from method_name to rosyMethod,
242+ the name of the ProtoRPC method to be called on the backend.
243+ If no rosyMethod was specified the value will be None.
244+
245+ Args:
246+ parsed_config: The JSON object with the API configuration being added.
247+ """
248+ methods = parsed_config .get ('methods' )
249+ if not methods :
250+ return
251+
252+ for method_name , method in methods .iteritems ():
253+ self .__api_methods [method_name ] = method .get ('rosyMethod' )
254+
255+ def lookup_api_method (self , api_method_name ):
256+ """Looks an API method up by name to find the backend method to call.
257+
258+ Args:
259+ api_method_name: Name of the method in the API that was called.
260+
261+ Returns:
262+ Name of the ProtoRPC method called on the backend, or None if not found.
263+ """
264+ return self .__api_methods .get (api_method_name )
265+
266+ def all_api_configs (self ):
267+ """Return a list of all API configration specs as registered above."""
268+ return self .__api_configs
269+
270+
186271class _ApiServer (object ):
187272 """ProtoRPC wrapper, registers APIs and formats errors for Google API Server.
188273
@@ -248,7 +333,7 @@ def __init__(self, api_services, **kwargs):
248333 for entry in api_services :
249334 self .base_paths .add (entry .api_info .base_path )
250335
251- self .api_config_registry = api_backend_service . ApiConfigRegistry ()
336+ self .api_config_registry = ApiConfigRegistry ()
252337 self .api_name_version_map = self .__create_name_version_map (api_services )
253338 protorpc_services = self .__register_services (self .api_name_version_map ,
254339 self .api_config_registry )
0 commit comments