Browse Source

Merge "RequestDetail"

changes/88/486188/33
Jenkins 2 years ago
parent
commit
da9fad5180
4 changed files with 69 additions and 68 deletions
  1. 2
    1
      mixmatch/extend/__init__.py
  2. 4
    4
      mixmatch/extend/base.py
  3. 6
    6
      mixmatch/extend/name_routing.py
  4. 57
    57
      mixmatch/proxy.py

+ 2
- 1
mixmatch/extend/__init__.py View File

@@ -34,9 +34,10 @@ def load_extensions():
34 34
 def get_matched_extensions(request):
35 35
     """Return list of matched extensions for request
36 36
 
37
-    :type request: Dict[]
37
+    :type request: mixmatch.proxy.RequestDetails
38 38
     :rtype: List[mixmatch.extend.base.Extension]
39 39
     """
40
+
40 41
     def _match(e):
41 42
         return e.obj if e.obj.matches(request) else None
42 43
 

+ 4
- 4
mixmatch/extend/base.py View File

@@ -59,7 +59,7 @@ class Route(object):
59 59
         return True
60 60
 
61 61
     def match(self, request):
62
-        return (self._match_service(request['service']) and
63
-                self._match_version(request['version']) and
64
-                self._match_method(request['method']) and
65
-                self._match_action(request['action']))
62
+        return (self._match_service(request.service) and
63
+                self._match_version(request.version) and
64
+                self._match_method(request.method) and
65
+                self._match_action(request.action))

+ 6
- 6
mixmatch/extend/name_routing.py View File

@@ -32,18 +32,18 @@ class NameRouting(base.Extension):
32 32
         return 'MM-SERVICE-PROVIDER' in headers
33 33
 
34 34
     def handle_request(self, request):
35
-        if self._is_targeted(request['headers']):
35
+        if self._is_targeted(request.headers):
36 36
             return
37 37
 
38 38
         body = jsonutils.loads(mm_request.data)
39
-        if request['service'] == 'image':
40
-            if request['version'] == 'v1':
41
-                name = request['headers'].get('X-IMAGE-META-NAME', '')
39
+        if request.service == 'image':
40
+            if request.version == 'v1':
41
+                name = request.headers.get('X-IMAGE-META-NAME', '')
42 42
             else:
43 43
                 name = body.get('name', '')
44
-        elif request['service'] == 'volume':
44
+        elif request.service == 'volume':
45 45
             name = body['volume'].get('name', '')
46 46
 
47 47
         name = name.split('@')
48 48
         if len(name) == 2:
49
-            request['headers']['MM-SERVICE-PROVIDER'] = name[1]
49
+            request.headers['MM-SERVICE-PROVIDER'] = name[1]

+ 57
- 57
mixmatch/proxy.py View File

@@ -52,25 +52,6 @@ def get_service(a):
52 52
             abort(404)
53 53
 
54 54
 
55
-def get_details(method, orig_path, headers):
56
-    """Get details for a request."""
57
-    path = orig_path.split('/')
58
-    # NOTE(knikolla): Request usually look like:
59
-    # /<service>/<version>/<project_id:uuid>/<res_type>/<res_id:uuid>
60
-    # or
61
-    # /<service>/<version>/<res_type>/<specific action>
62
-    return {'method': method,
63
-            'service': get_service(path),
64
-            'version': utils.safe_pop(path),
65
-            'project_id': utils.pop_if_uuid(path),
66
-            'action': path[:],  # NOTE(knikolla): This includes
67
-            'resource_type': utils.safe_pop(path),  # this
68
-            'resource_id': utils.pop_if_uuid(path),  # and this
69
-            'token': headers.get('X-AUTH-TOKEN', None),
70
-            'headers': dict(headers),
71
-            'path': orig_path}
72
-
73
-
74 55
 def is_json_response(response):
75 56
     return response.headers.get('Content-Type') == 'application/json'
76 57
 
@@ -96,14 +77,33 @@ def format_for_log(title=None, method=None, url=None, headers=None,
96 77
     ])
97 78
 
98 79
 
80
+class RequestDetails(object):
81
+    def __init__(self, method, orig_path, headers):
82
+        local_path = orig_path.split('/')
83
+        # NOTE(knikolla): Request usually looks like this:
84
+        # /<service>/<version>/<project_id:uuid>/<res_type>/<res_id:uuid>
85
+        # or
86
+        # /<service>/<version>/<res_type>/<specific action>
87
+        self.method = method
88
+        self.service = get_service(local_path)
89
+        self.version = utils.safe_pop(local_path)
90
+        self.project_id = utils.pop_if_uuid(local_path)
91
+        self.action = local_path[:]  # NOTE(knikolla): This includes
92
+        self.resource_type = utils.safe_pop(local_path)  # this
93
+        self.resource_id = utils.pop_if_uuid(local_path)  # and this
94
+        self.token = headers.get('X-AUTH-TOKEN', None)
95
+        self.headers = dict(headers)
96
+        self.path = orig_path
97
+
98
+
99 99
 class RequestHandler(object):
100 100
 
101 101
     def __init__(self, method, path, headers):
102
-        self.details = get_details(method, path, headers)
102
+        self.details = RequestDetails(method, path, headers)
103 103
         self.extensions = extend.get_matched_extensions(self.details)
104 104
         self._set_strip_details(self.details)
105 105
         self.enabled_sps = filter(
106
-            lambda sp: (self.details['service'] in
106
+            lambda sp: (self.details.service in
107 107
                         service_providers.get(CONF, sp).enabled_services),
108 108
             CONF.service_providers
109 109
         )
@@ -111,7 +111,7 @@ class RequestHandler(object):
111 111
         for extension in self.extensions:
112 112
             extension.handle_request(self.details)
113 113
 
114
-        if not self.details['version']:
114
+        if not self.details.version:
115 115
             if CONF.aggregation:
116 116
                 # unversioned calls with no action
117 117
                 self._forward = self._list_api_versions
@@ -119,32 +119,32 @@ class RequestHandler(object):
119 119
                 self._forward = self._local_forward
120 120
             return
121 121
 
122
-        if not self.details['resource_type']:
122
+        if not self.details.resource_type:
123 123
             # versioned calls with no action
124 124
             abort(400)
125 125
 
126 126
         mapping = None
127 127
 
128
-        if self.details['resource_id']:
128
+        if self.details.resource_id:
129 129
             mapping = model.ResourceMapping.find(
130
-                resource_type=self.details['action'][0],
131
-                resource_id=self.details['resource_id'])
130
+                resource_type=self.details.action[0],
131
+                resource_id=self.details.resource_id)
132 132
 
133
-        LOG.debug('Local Token: %s ' % self.details['token'])
133
+        LOG.debug('Local Token: %s ' % self.details.token)
134 134
 
135
-        if 'MM-SERVICE-PROVIDER' in self.details['headers']:
135
+        if 'MM-SERVICE-PROVIDER' in self.details.headers:
136 136
             # The user wants a specific service provider, use that SP.
137 137
             # FIXME(knikolla): This isn't exercised by any unit test
138 138
             (self.service_provider, self.project_id) = (
139
-                self.details['headers']['MM-SERVICE-PROVIDER'],
140
-                self.details['headers'].get('MM-PROJECT-ID', None)
139
+                self.details.headers['MM-SERVICE-PROVIDER'],
140
+                self.details.headers.get('MM-PROJECT-ID', None)
141 141
             )
142 142
             if self.service_provider not in self.enabled_sps:
143 143
                 abort(400)
144 144
             if not self.project_id and self.service_provider != 'default':
145 145
                 self.project_id = auth.get_projects_at_sp(
146 146
                     self.service_provider,
147
-                    self.details['token']
147
+                    self.details.token
148 148
                 )[0]
149 149
             self._forward = self._targeted_forward
150 150
         elif mapping:
@@ -156,19 +156,19 @@ class RequestHandler(object):
156 156
             self._forward = self._forward
157 157
 
158 158
         LOG.info(format_for_log(title="Request to proxy",
159
-                                method=self.details['method'],
160
-                                url=self.details['path'],
161
-                                headers=dict(self.details['headers'])))
159
+                                method=self.details.method,
160
+                                url=self.details.path,
161
+                                headers=dict(self.details.headers)))
162 162
 
163 163
     def _do_request_on(self, sp, project_id=None):
164
-        headers = self._prepare_headers(self.details['headers'])
164
+        headers = self._prepare_headers(self.details.headers)
165 165
 
166
-        if self.details['token']:
166
+        if self.details.token:
167 167
             if sp == 'default':
168
-                auth_session = auth.get_local_auth(self.details['token'])
168
+                auth_session = auth.get_local_auth(self.details.token)
169 169
             else:
170 170
                 auth_session = auth.get_sp_auth(sp,
171
-                                                self.details['token'],
171
+                                                self.details.token,
172 172
                                                 project_id)
173 173
             headers['X-AUTH-TOKEN'] = auth_session.get_token()
174 174
             project_id = auth_session.get_project_id()
@@ -177,14 +177,14 @@ class RequestHandler(object):
177 177
 
178 178
         url = services.construct_url(
179 179
             sp,
180
-            self.details['service'],
181
-            self.details['version'],
182
-            self.details['action'],
180
+            self.details.service,
181
+            self.details.version,
182
+            self.details.action,
183 183
             project_id=project_id
184 184
         )
185 185
 
186 186
         request_kwargs = {
187
-            'method': self.details['method'],
187
+            'method': self.details.method,
188 188
             'url': url,
189 189
             'headers': headers,
190 190
             'params': self._prepare_args(request.args)
@@ -197,7 +197,7 @@ class RequestHandler(object):
197 197
                                         stream=self.stream,
198 198
                                         **request_kwargs)
199 199
         LOG.info(format_for_log(title='Request from proxy',
200
-                                method=self.details['method'],
200
+                                method=self.details.method,
201 201
                                 url=url,
202 202
                                 headers=headers))
203 203
         LOG.info(format_for_log(title='Response to proxy',
@@ -246,7 +246,7 @@ class RequestHandler(object):
246 246
                 else:
247 247
                     errors[r.status_code].append(r)
248 248
             else:
249
-                for p in auth.get_projects_at_sp(sp, self.details['token']):
249
+                for p in auth.get_projects_at_sp(sp, self.details.token):
250 250
                     r = self._do_request_on(sp, p)
251 251
                     if 200 <= r.status_code < 300:
252 252
                         responses[(sp, p)] = r
@@ -262,9 +262,9 @@ class RequestHandler(object):
262 262
             # for everything that is returned.
263 263
             return flask.Response(
264 264
                 services.aggregate(responses,
265
-                                   self.details['action'][0],
266
-                                   self.details['service'],
267
-                                   version=self.details['version'],
265
+                                   self.details.action[0],
266
+                                   self.details.service,
267
+                                   version=self.details.version,
268 268
                                    params=dict(request.args),
269 269
                                    path=request.base_url,
270 270
                                    strip_details=self.strip_details),
@@ -284,7 +284,7 @@ class RequestHandler(object):
284 284
         return flask.Response("Something strange happened.\n", 500)
285 285
 
286 286
     def _list_api_versions(self):
287
-        return services.list_api_versions(self.details['service'],
287
+        return services.list_api_versions(self.details.service,
288 288
                                           request.base_url)
289 289
 
290 290
     def forward(self):
@@ -318,12 +318,12 @@ class RequestHandler(object):
318 318
 
319 319
     @utils.CachedProperty
320 320
     def chunked(self):
321
-        encoding = self.details['headers'].get('Transfer-Encoding', '')
321
+        encoding = self.details.headers.get('Transfer-Encoding', '')
322 322
         return encoding.lower() == 'chunked'
323 323
 
324 324
     @utils.CachedProperty
325 325
     def stream(self):
326
-        return self.details['method'] == 'GET'
326
+        return self.details.method == 'GET'
327 327
 
328 328
     @utils.CachedProperty
329 329
     def fallback_to_local(self):
@@ -334,9 +334,9 @@ class RequestHandler(object):
334 334
     @utils.CachedProperty
335 335
     def aggregate(self):
336 336
         """Return true if this is a case where we should aggregate."""
337
-        return (not self.details['resource_id'] and
338
-                self.details['method'] == 'GET' and
339
-                self.details['action'][0] in RESOURCES_AGGREGATE)
337
+        return (not self.details.resource_id and
338
+                self.details.method == 'GET' and
339
+                self.details.action[0] in RESOURCES_AGGREGATE)
340 340
 
341 341
     @utils.CachedProperty
342 342
     def session(self):
@@ -356,11 +356,11 @@ class RequestHandler(object):
356 356
         # if request is to /volumes, change it
357 357
         # to /volumes/detail for aggregation
358 358
         # and set strip_details to true
359
-        if (details['service'] == 'volume' and
360
-                details['method'] == 'GET' and
361
-                utils.safe_get(details['action'], -1) == 'volumes'):
359
+        if (details.service == 'volume' and
360
+                details.method == 'GET' and
361
+                utils.safe_get(details.action, -1) == 'volumes'):
362 362
             self.strip_details = True
363
-            details['action'].insert(len(details['action']), 'detail')
363
+            details.action.insert(len(details.action), 'detail')
364 364
         else:
365 365
             self.strip_details = False
366 366
 

Loading…
Cancel
Save