Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Side by Side Diff: third_party/google-endpoints/endpoints/api_backend_service.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 Google Inc. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """API serving config collection service implementation.
16
17 Contains the implementation for BackendService as defined in api_backend.py.
18 """
19
20 # pylint: disable=g-statement-before-imports,g-import-not-at-top
21 try:
22 import json
23 except ImportError:
24 import simplejson as json
25
26 import logging
27
28 import api_backend
29 import api_exceptions
30
31 from protorpc import message_types
32
33 __all__ = [
34 'ApiConfigRegistry',
35 'BackendServiceImpl',
36 ]
37
38
39 class ApiConfigRegistry(object):
40 """Registry of active APIs to be registered with Google API Server."""
41
42 def __init__(self):
43 # Set of API classes that have been registered.
44 self.__registered_classes = set()
45 # Set of API config contents served by this App Engine AppId/version
46 self.__api_configs = set()
47 # Map of API method name to ProtoRPC method name.
48 self.__api_methods = {}
49
50 # pylint: disable=g-bad-name
51 def register_backend(self, config_contents):
52 """Register a single API and its config contents.
53
54 Args:
55 config_contents: String containing API configuration.
56 """
57 if config_contents is None:
58 return
59 parsed_config = json.loads(config_contents)
60 self.__register_class(parsed_config)
61 self.__api_configs.add(config_contents)
62 self.__register_methods(parsed_config)
63
64 def __register_class(self, parsed_config):
65 """Register the class implementing this config, so we only add it once.
66
67 Args:
68 parsed_config: The JSON object with the API configuration being added.
69
70 Raises:
71 ApiConfigurationError: If the class has already been registered.
72 """
73 methods = parsed_config.get('methods')
74 if not methods:
75 return
76
77 # Determine the name of the class that implements this configuration.
78 service_classes = set()
79 for method in methods.itervalues():
80 rosy_method = method.get('rosyMethod')
81 if rosy_method and '.' in rosy_method:
82 method_class = rosy_method.split('.', 1)[0]
83 service_classes.add(method_class)
84
85 for service_class in service_classes:
86 if service_class in self.__registered_classes:
87 raise api_exceptions.ApiConfigurationError(
88 'API class %s has already been registered.' % service_class)
89 self.__registered_classes.add(service_class)
90
91 def __register_methods(self, parsed_config):
92 """Register all methods from the given api config file.
93
94 Methods are stored in a map from method_name to rosyMethod,
95 the name of the ProtoRPC method to be called on the backend.
96 If no rosyMethod was specified the value will be None.
97
98 Args:
99 parsed_config: The JSON object with the API configuration being added.
100 """
101 methods = parsed_config.get('methods')
102 if not methods:
103 return
104
105 for method_name, method in methods.iteritems():
106 self.__api_methods[method_name] = method.get('rosyMethod')
107
108 def lookup_api_method(self, api_method_name):
109 """Looks an API method up by name to find the backend method to call.
110
111 Args:
112 api_method_name: Name of the method in the API that was called.
113
114 Returns:
115 Name of the ProtoRPC method called on the backend, or None if not found.
116 """
117 return self.__api_methods.get(api_method_name)
118
119 def all_api_configs(self):
120 """Return a list of all API configration specs as registered above."""
121 return list(self.__api_configs)
122
123
124 class BackendServiceImpl(api_backend.BackendService):
125 """Implementation of BackendService."""
126
127 def __init__(self, api_config_registry, app_revision):
128 """Create a new BackendService implementation.
129
130 Args:
131 api_config_registry: ApiConfigRegistry to register and look up configs.
132 app_revision: string containing the current app revision.
133 """
134 self.__api_config_registry = api_config_registry
135 self.__app_revision = app_revision
136
137 # pylint: disable=g-bad-name
138 # pylint: disable=g-doc-return-or-yield
139 # pylint: disable=g-doc-args
140 @staticmethod
141 def definition_name():
142 """Override definition_name so that it is not BackendServiceImpl."""
143 return api_backend.BackendService.definition_name()
144
145 def getApiConfigs(self, request=None):
146 """Return a list of active APIs and their configuration files.
147
148 Args:
149 request: A request which may contain an app revision
150
151 Returns:
152 ApiConfigList: A list of API config strings
153 """
154 if (request and request.appRevision and
155 request.appRevision != self.__app_revision):
156 raise api_exceptions.BadRequestException(
157 message='API backend app revision %s not the same as expected %s' % (
158 self.__app_revision, request.appRevision))
159
160 configs = self.__api_config_registry.all_api_configs()
161 return api_backend.ApiConfigList(items=configs)
162
163 def logMessages(self, request):
164 """Write a log message from the Swarm FE to the log.
165
166 Args:
167 request: A log message request.
168
169 Returns:
170 Void message.
171 """
172 Level = api_backend.LogMessagesRequest.LogMessage.Level
173 log = logging.getLogger(__name__)
174 for message in request.messages:
175 level = message.level if message.level is not None else Level.info
176 # Create a log record and override the pathname and lineno. These
177 # messages come from the front end, so it's misleading to say that they
178 # come from api_backend_service.
179 record = logging.LogRecord(name=__name__, level=level.number, pathname='',
180 lineno='', msg=message.message, args=None,
181 exc_info=None)
182 log.handle(record)
183
184 return message_types.VoidMessage()
OLDNEW
« no previous file with comments | « third_party/google-endpoints/endpoints/api_backend.py ('k') | third_party/google-endpoints/endpoints/api_config.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698