diff --git a/doc/source/index.rst b/doc/source/index.rst index 344ee3c..a0b8d40 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -43,6 +43,18 @@ forward reverse A mapping of aliases to official service type. +primary_service_by_project + A mapping of project names to the primary service associated with that + project. Every project has only one primary service. + +all_types_by_service_type + A mapping of service type to a list containing the official service type + and all of its aliases. Contains an entry for every service. + +service_types_by_project + A mapping of project name to a list of all service types associated with + that project. + The published format is described by a :download:`Service Types Authority Published Schema `. diff --git a/published-schema.json b/published-schema.json index 352fece..f2b04c0 100644 --- a/published-schema.json +++ b/published-schema.json @@ -45,6 +45,42 @@ "description": "Official service-type" } } + }, + "primary_service_by_project": { + "type": "object", + "description": "Mapping of project name to the service data for the primary service", + "patternProperties": { + "^.*$": { + "$ref": "https://specs.openstack.org/openstack/service-types-authority/_downloads/schema.json#/definitions/service" + } + } + }, + "all_types_by_service_type": { + "type": "object", + "description": "Mapping of official service-type to official type and aliases", + "patternProperties": { + "^([a-z][a-z-]*[a-z]+|ec2-api)$": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Ordered list of official type and historical aliases." + } + }, + "additionalProperties": false + }, + "service_types_by_project": { + "type": "object", + "description": "Mapping of project name to list of service-types for the project", + "patternProperties": { + "^([a-z][a-z-]*[a-z]+|ec2-api)$": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of service types associated with a project" + } + } } } } diff --git a/transform.py b/transform.py index 226a4cc..a1f9fc5 100644 --- a/transform.py +++ b/transform.py @@ -64,14 +64,29 @@ def main(): ['git', 'rev-parse', 'HEAD']).decode('utf-8').strip() mapping['forward'] = {} mapping['reverse'] = {} + mapping['primary_service_by_project'] = {} + mapping['all_types_by_service_type'] = {} + mapping['service_types_by_project'] = {} for service in mapping['services']: service_type = service['service_type'] + mapping['all_types_by_service_type'][service_type] = [service_type] if 'aliases' in service: aliases = service['aliases'] mapping['forward'][service_type] = aliases + mapping['all_types_by_service_type'][service_type].extend(aliases) for alias in aliases: mapping['reverse'][alias] = service_type + for key in ('project', 'api_reference_project'): + name = service.get(key) + if name: + if not service.get('secondary', False): + mapping['primary_service_by_project'][name] = service + project_types = mapping['service_types_by_project'].get( + name, []) + if service_type not in project_types: + project_types.append(service_type) + mapping['service_types_by_project'][name] = project_types schema = json.load(open('published-schema.json', 'r')) resolver = LocalResolver.from_schema(schema) diff --git a/validate.py b/validate.py index 0ad9175..f4f4743 100644 --- a/validate.py +++ b/validate.py @@ -27,12 +27,13 @@ def validate_schema(schema, data, resolver=None): def validate_unique_tokens(data): - """Ensure service types and aliases are all unique tokens. + """Ensure service types, aliases and primary projects are all unique. :return: An iterator over messages for any errors encountered. """ service_types = [] aliases = [] + projects = [] for service in data['services']: service_types.append(service['service_type']) if "aliases" in service: @@ -40,6 +41,13 @@ def validate_unique_tokens(data): if alias in aliases: yield "Alias '{alias}' appears twice".format(alias=alias) aliases.append(alias) + if service.get('secondary', False): + continue + if service['project'] in projects: + yield "'{service}' is duplicate service from '{project}'".format( + service=service['service_type'], + project=service['project']) + projects.append(service['project']) for alias in aliases: if alias in service_types: yield "Alias '{alias}' conflicts with a service_type".format(