Skip to content

Commit

Permalink
Get less confused about what the service ID refers to.
Browse files Browse the repository at this point in the history
In order to reflect what the API service is actually doing, it's an identifier for the IAPIMock provider, not an individual enpdoint, since an individual endpoint can't be reliably identified across tenants.  This also changes the URIs so that the service ID comes first, before the region, since region names only really exist *within the context* of a particular IAPIMock plugin.
  • Loading branch information
glyph committed Aug 13, 2014
1 parent 62d2cd1 commit 3bf954e
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 36 deletions.
8 changes: 4 additions & 4 deletions mimic/canned_responses/auth.py
Expand Up @@ -25,7 +25,7 @@ def format_timestamp(dt):

def get_token(tenant_id,
entry_generator,
prefix_for_entry,
prefix_for_endpoint,
timestamp=format_timestamp,
response_token=HARD_CODED_TOKEN,
response_user_id=HARD_CODED_USER_ID,
Expand All @@ -51,7 +51,7 @@ def endpoint_json():
"region": endpoint.region,
"tenantId": endpoint.tenant_id,
"publicURL": endpoint.url_with_prefix(
prefix_for_entry(entry)
prefix_for_endpoint(endpoint)
),
}
yield {
Expand Down Expand Up @@ -81,7 +81,7 @@ def endpoint_json():
}


def get_endpoints(tenant_id, entry_generator, prefix_for_entry):
def get_endpoints(tenant_id, entry_generator, prefix_for_endpoint):
"""
Canned response for Identity's get endpoints call. This returns endpoints
only for the services implemented by Mimic.
Expand All @@ -96,7 +96,7 @@ def get_endpoints(tenant_id, entry_generator, prefix_for_entry):
"region": endpoint.region,
"tenantId": endpoint.tenant_id,
"publicURL": endpoint.url_with_prefix(
prefix_for_entry(entry)
prefix_for_endpoint(endpoint)
),
"name": entry.name,
"type": entry.type,
Expand Down
63 changes: 37 additions & 26 deletions mimic/core.py
Expand Up @@ -62,15 +62,13 @@ def __init__(self, clock, apis):
# mapping of token (unicode) to username (unicode: key in
# _token_to_session)
}
self.uri_prefixes = {
# map of (region, service_id) to (somewhat ad-hoc interface) "Api"
# object.
}
self._api_to_uuid = {}
self._uuid_to_api = {}

for api in apis:
entries = api.catalog_entries(tenant_id=None)
for entry in entries:
for endpoint in entry.endpoints:
self.uri_prefixes[(endpoint.region, str(uuid4()))] = api
this_api_id = str(uuid4())
self._api_to_uuid[api] = this_api_id
self._uuid_to_api[this_api_id] = api

@classmethod
def fromPlugins(cls, clock):
Expand Down Expand Up @@ -192,41 +190,54 @@ def service_with_region(self, region_name, service_id, base_uri):
:return: A resource.
:rtype: :obj:`twisted.web.iweb.IResource`
"""
key = (region_name, service_id)
if key in self.uri_prefixes:
return self.uri_prefixes[key].resource_for_region(
self.uri_for_service(region_name, service_id, base_uri))
if service_id in self._uuid_to_api:
api = self._uuid_to_api[service_id]
return api.resource_for_region(
self.uri_for_service(region_name, service_id, base_uri)
)

def uri_for_service(self, region, service_id, base_uri):
"""
Generate a URI prefix for a given region and service ID.
:param unicode region_name: the name of the region that the service
resource exists within.
:param unicode service_id: the UUID for the service for the
specified region
:param str base_uri: the base uri to use instead of the default -
most likely comes from a request URI
Each plugin loaded into mimic generates a list of catalog entries; each
catalog entry has a list of endpoints. Each endpoint has a URI
associated with it, which we call a "URI prefix", because the endpoint
will have numerous other URIs beneath it in the hierarchy, generally
starting with a version number and tenant ID. The URI prefixes
generated for this function point to the top of the endpoint's
hierarchy, not including any tenant information.
:param unicode region: the name of the region that the service resource
exists within.
:param unicode service_id: the UUID for the service for the specified
region
:param str base_uri: the base uri to use instead of the default - most
likely comes from a request URI
:return: The full URI locating the service for that region
:rtype: ``str``
"""
return str(URLPath.fromString(base_uri)
.child("service").child(region).child(service_id).child(""))
.child("service").child(service_id).child(region).child(""))

def entries_for_tenant(self, tenant_id, prefix_map, base_uri):
"""
Get all the :obj:`mimic.catalog.Entry` objects for the given tenant
ID.
Get all the :obj:`mimic.catalog.Entry` objects for the given tenant ID,
populating a mapping of :obj:`mimic.catalog.Entry` to URI prefixes (as
described by :pyobj:`MimicCore.uri_for_service`) for that entry.
:param unicode tenant_id: A fictional tenant ID.
:param dict prefix_map: a mapping of entries to uris
:param str base_uri: the base uri to use instead of the default -
most likely comes from a request URI
:param str base_uri: the base uri to use instead of the default - most
likely comes from a request URI
:return: The full URI locating the service for that region
"""
for (region, service_id), api in sorted(self.uri_prefixes.items()):
for service_id, api in self._uuid_to_api.items():
for entry in api.catalog_entries(tenant_id):
prefix_map[entry] = self.uri_for_service(region, service_id,
base_uri)
for endpoint in entry.endpoints:
prefix_map[endpoint] = self.uri_for_service(
endpoint.region, service_id, base_uri
)
yield entry
4 changes: 2 additions & 2 deletions mimic/resource.py
Expand Up @@ -49,9 +49,9 @@ def get_mimic_presets(self, request):
request.setResponseCode(200)
return json.dumps(get_presets)

@app.route("/service/<string:region_name>/<string:service_id>",
@app.route("/service/<string:service_id>/<string:region_name>",
branch=True)
def get_service_resource(self, request, region_name, service_id):
def get_service_resource(self, request, service_id, region_name):
"""
Based on the URL prefix of a region and a service, where the region is
an identifier (like ORD, DFW, etc) and service is a
Expand Down
4 changes: 2 additions & 2 deletions mimic/rest/auth_api.py
Expand Up @@ -54,7 +54,7 @@ def lookup(entry):
entry_generator=lambda tenant_id:
list(self.core.entries_for_tenant(
tenant_id, prefix_map, base_uri_from_request(request))),
prefix_for_entry=lookup,
prefix_for_endpoint=lookup,
response_token=session.token,
response_user_id=session.user_id,
response_user_name=session.username,
Expand Down Expand Up @@ -103,7 +103,7 @@ def get_endpoints_for_token(self, request, token_id):
entry_generator=lambda tenant_id: list(
self.core.entries_for_tenant(tenant_id, prefix_map,
base_uri_from_request(request))),
prefix_for_entry=prefix_map.get)
prefix_for_endpoint=prefix_map.get)
)


Expand Down
4 changes: 2 additions & 2 deletions mimic/test/test_auth.py
Expand Up @@ -79,7 +79,7 @@ def test_tokens_response(self):
get_token(
tenant_id=tenant_id, timestamp=lambda dt: "<<<timestamp>>>",
entry_generator=example_endpoints(lambda: 1),
prefix_for_entry=lambda e: 'prefix'
prefix_for_endpoint=lambda e: 'prefix'
),
{
"access": {
Expand Down Expand Up @@ -159,7 +159,7 @@ def counter():
get_endpoints(
tenant_id=tenant_id,
entry_generator=example_endpoints(counter),
prefix_for_entry=lambda e: 'prefix'
prefix_for_endpoint=lambda e: 'prefix'
),
{
"endpoints": [
Expand Down

0 comments on commit 3bf954e

Please sign in to comment.