'Retrieve and format the V2 service catalog.
:param user_id: The id of the user who has been authenticated for
creating service catalog.
:param project_id: The id of the project. \'project_id\' will be None in
the case this being called to create a catalog to go in a domain
scoped token. In this case, any endpoint that requires a project_id
as part of their URL will be skipped.
:returns: A nested dict representing the service catalog or an
empty dict.'

def get_catalog(self, user_id, project_id):

    substitutions = dict(itertools.chain(CONF.items(), CONF.eventlet_server.items()))
    substitutions.update({'user_id': user_id})
    silent_keyerror_failures = []
    if project_id:
        substitutions.update({'tenant_id': project_id, 'project_id': project_id})
    else:
        silent_keyerror_failures = ['tenant_id', 'project_id']
    catalog = {}
    for (region, region_ref) in self.templates.items():
        catalog[region] = {}
        for (service, service_ref) in region_ref.items():
            service_data = {}
            try:
                for (k, v) in service_ref.items():
                    formatted_value = utils.format_url(v, substitutions, silent_keyerror_failures=silent_keyerror_failures)
                    if formatted_value:
                        service_data[k] = formatted_value
            except exception.MalformedEndpoint:
                continue
            catalog[region][service] = service_data
    return catalog
