diff --git a/rest-api-templates/ari_model_validators.c.mustache b/rest-api-templates/ari_model_validators.c.mustache index 7bb52789841939bb184f3b5fc998c5a90b587d97..9d316715630131cada0fd0109c4d49ab3d585256 100644 --- a/rest-api-templates/ari_model_validators.c.mustache +++ b/rest-api-templates/ari_model_validators.c.mustache @@ -57,11 +57,11 @@ int ast_ari_validate_{{c_id}}(struct ast_json *json) if (strcmp("{{id}}", discriminator) == 0) { /* Self type; fall through */ } else -{{#subtypes}} +{{#all_subtypes}} if (strcmp("{{id}}", discriminator) == 0) { return ast_ari_validate_{{c_id}}(json); } else -{{/subtypes}} +{{/all_subtypes}} { ast_log(LOG_ERROR, "ARI {{id}} has undocumented subtype %s\n", discriminator); diff --git a/rest-api-templates/models.wiki.mustache b/rest-api-templates/models.wiki.mustache index b2e742afc4df3293b5cb234569e01192ff0909a3..2bc1e467f1afcac769889f9933a8cf9eea682d49 100644 --- a/rest-api-templates/models.wiki.mustache +++ b/rest-api-templates/models.wiki.mustache @@ -5,7 +5,7 @@ {{#models}} h1. {{id}} {{#extends}}Base type: [{{extends}}|#{{extends}}]{{/extends}} -{{#has_subtypes}}Subtypes:{{#subtypes}} [{{id}}|#{{id}}]{{/subtypes}}{{/has_subtypes}} +{{#has_subtypes}}Subtypes:{{#all_subtypes}} [{{id}}|#{{id}}]{{/all_subtypes}}{{/has_subtypes}} {{#wiki_description}} {{{wiki_description}}} diff --git a/rest-api-templates/swagger_model.py b/rest-api-templates/swagger_model.py index af52266b409b398d1de0ed7a1ae1aaf75d21aa5b..be98c4a3c02aaa2713e8bdd45820360f81701213 100644 --- a/rest-api-templates/swagger_model.py +++ b/rest-api-templates/swagger_model.py @@ -33,8 +33,8 @@ import re import sys import traceback -# I'm not quite sure what was in Swagger 1.2, but apparently I missed it -SWAGGER_VERSIONS = ["1.1", "1.3"] +# We don't fully support Swagger 1.2, but we need it for subtyping +SWAGGER_VERSIONS = ["1.1", "1.2"] SWAGGER_PRIMITIVES = [ 'void', @@ -479,13 +479,13 @@ class Model(Stringify): def __init__(self): self.id = None - self.extends = None - self.extends_type = None + self.subtypes = [] + self.__subtype_types = [] self.notes = None self.description = None self.__properties = None self.__discriminator = None - self.__subtypes = [] + self.__extends_type = None def load(self, id, model_json, processor, context): context = context.next_stack(model_json, 'id') @@ -494,9 +494,9 @@ class Model(Stringify): self.id = model_json.get('id') if id != self.id: raise SwaggerError("Model id doesn't match name", context) - self.extends = model_json.get('extends') - if self.extends and context.version_less_than("1.3"): - raise SwaggerError("Type extension support added in Swagger 1.3", + self.subtypes = model_json.get('subTypes') or [] + if self.subtypes and context.version_less_than("1.2"): + raise SwaggerError("Type extension support added in Swagger 1.2", context) self.description = model_json.get('description') props = model_json.get('properties').items() or [] @@ -507,8 +507,8 @@ class Model(Stringify): discriminator = model_json.get('discriminator') if discriminator: - if context.version_less_than("1.3"): - raise SwaggerError("Discriminator support added in Swagger 1.3", + if context.version_less_than("1.2"): + raise SwaggerError("Discriminator support added in Swagger 1.2", context) discr_props = [p for p in self.__properties if p.name == discriminator] @@ -526,43 +526,42 @@ class Model(Stringify): processor.process_model(self, context) return self - def add_subtype(self, subtype): - """Add subtype to this model. - - @param subtype: Model instance for the subtype. - """ - self.__subtypes.append(subtype) + def extends(self): + return self.__extends_type and self.__extends_type.id def set_extends_type(self, extends_type): - self.extends_type = extends_type + self.__extends_type = extends_type + + def set_subtype_types(self, subtype_types): + self.__subtype_types = subtype_types def discriminator(self): """Returns the discriminator, digging through base types if needed. """ return self.__discriminator or \ - self.extends_type and self.extends_type.discriminator() + self.__extends_type and self.__extends_type.discriminator() def properties(self): base_props = [] - if self.extends_type: - base_props = self.extends_type.properties() + if self.__extends_type: + base_props = self.__extends_type.properties() return base_props + self.__properties def has_properties(self): return len(self.properties()) > 0 - def subtypes(self): - """Returns the full list of all subtypes. + def all_subtypes(self): + """Returns the full list of all subtypes, including sub-subtypes. """ - res = self.__subtypes + \ - [subsubtypes for subtype in self.__subtypes - for subsubtypes in subtype.subtypes()] + res = self.__subtype_types + \ + [subsubtypes for subtype in self.__subtype_types + for subsubtypes in subtype.all_subtypes()] return sorted(res, key=lambda m: m.id) def has_subtypes(self): """Returns True if type has any subtypes. """ - return len(self.subtypes()) > 0 + return len(self.subtypes) > 0 class ApiDeclaration(Stringify): @@ -641,13 +640,16 @@ class ApiDeclaration(Stringify): # Now link all base/extended types model_dict = dict((m.id, m) for m in self.models) for m in self.models: - if m.extends: - extends_type = model_dict.get(m.extends) - if not extends_type: - raise SwaggerError("%s extends non-existing model %s", - m.id, m.extends) - extends_type.add_subtype(m) - m.set_extends_type(extends_type) + def link_subtype(name): + res = model_dict.get(subtype) + if not res: + raise SwaggerError("%s has non-existing subtype %s", + m.id, name) + res.set_extends_type(m) + return res; + if m.subtypes: + m.set_subtype_types([ + link_subtype(subtype) for subtype in m.subtypes]) return self diff --git a/rest-api/api-docs/events.json b/rest-api/api-docs/events.json index ac3f6521cdd5f1b40b248d709ede45539a7bc8de..a9ea45c81c899461327dfc2fb1528c770d0f0485 100644 --- a/rest-api/api-docs/events.json +++ b/rest-api/api-docs/events.json @@ -3,7 +3,7 @@ "_author": "David M. Lee, II <dlee@digium.com>", "_svn_revision": "$Revision$", "apiVersion": "0.0.1", - "swaggerVersion": "1.3", + "swaggerVersion": "1.2", "basePath": "http://localhost:8088/stasis", "resourcePath": "/api-docs/events.{format}", "apis": [ @@ -43,11 +43,14 @@ "required": true, "description": "Indicates the type of this message." } - } + }, + "subTypes": [ + "MissingParams", + "Event" + ] }, "MissingParams": { "id": "MissingParams", - "extends": "Message", "description": "Error event sent when required params are missing.", "properties": { "params": { @@ -59,7 +62,6 @@ }, "Event": { "id": "Event", - "extends": "Message", "description": "Base type for asynchronous events from Asterisk.", "properties": { "application": { @@ -72,11 +74,32 @@ "description": "Time at which this event was created.", "required": false } - } + }, + "subTypes": [ + "PlaybackStarted", + "PlaybackFinished", + "ApplicationReplaced", + "BridgeCreated", + "BridgeDestroyed", + "BridgeMerged", + "ChannelCreated", + "ChannelDestroyed", + "ChannelEnteredBridge", + "ChannelLeftBridge", + "ChannelStateChange", + "ChannelDtmfReceived", + "ChannelDialplan", + "ChannelCallerId", + "ChannelUserevent", + "ChannelHangupRequest", + "ChannelVarset", + "EndpointStateChange", + "StasisEnd", + "StasisStart" + ] }, "PlaybackStarted": { "id": "PlaybackStarted", - "extends": "Event", "description": "Event showing the start of a media playback operation.", "properties": { "playback": { @@ -88,7 +111,6 @@ }, "PlaybackFinished": { "id": "PlaybackFinished", - "extends": "Event", "description": "Event showing the completion of a media playback operation.", "properties": { "playback": { @@ -100,13 +122,11 @@ }, "ApplicationReplaced": { "id": "ApplicationReplaced", - "extends": "Event", "description": "Notification that another WebSocket has taken over for an application.\n\nAn application may only be subscribed to by a single WebSocket at a time. If multiple WebSockets attempt to subscribe to the same application, the newer WebSocket wins, and the older one receives this event.", "properties": {} }, "BridgeCreated": { "id": "BridgeCreated", - "extends": "Event", "description": "Notification that a bridge has been created.", "properties": { "bridge": { @@ -117,7 +137,6 @@ }, "BridgeDestroyed": { "id": "BridgeDestroyed", - "extends": "Event", "description": "Notification that a bridge has been destroyed.", "properties": { "bridge": { @@ -128,7 +147,6 @@ }, "BridgeMerged": { "id": "BridgeMerged", - "extends": "Event", "description": "Notification that one bridge has merged into another.", "properties": { "bridge": { @@ -143,7 +161,6 @@ }, "ChannelCreated": { "id": "ChannelCreated", - "extends": "Event", "description": "Notification that a channel has been created.", "properties": { "channel": { @@ -154,7 +171,6 @@ }, "ChannelDestroyed": { "id": "ChannelDestroyed", - "extends": "Event", "description": "Notification that a channel has been destroyed.", "properties": { "cause": { @@ -175,7 +191,6 @@ }, "ChannelEnteredBridge": { "id": "ChannelEnteredBridge", - "extends": "Event", "description": "Notification that a channel has entered a bridge.", "properties": { "bridge": { @@ -189,7 +204,6 @@ }, "ChannelLeftBridge": { "id": "ChannelLeftBridge", - "extends": "Event", "description": "Notification that a channel has left a bridge.", "properties": { "bridge": { @@ -204,7 +218,6 @@ }, "ChannelStateChange": { "id": "ChannelStateChange", - "extends": "Event", "description": "Notification of a channel's state change.", "properties": { "channel": { @@ -215,7 +228,6 @@ }, "ChannelDtmfReceived": { "id": "ChannelDtmfReceived", - "extends": "Event", "description": "DTMF received on a channel.\n\nThis event is sent when the DTMF ends. There is no notification about the start of DTMF", "properties": { "digit": { @@ -237,7 +249,6 @@ }, "ChannelDialplan": { "id": "ChannelDialplan", - "extends": "Event", "description": "Channel changed location in the dialplan.", "properties": { "channel": { @@ -259,7 +270,6 @@ }, "ChannelCallerId": { "id": "ChannelCallerId", - "extends": "Event", "description": "Channel changed Caller ID.", "properties": { "caller_presentation": { @@ -281,7 +291,6 @@ }, "ChannelUserevent": { "id": "ChannelUserevent", - "extends": "Event", "description": "User-generated event with additional user-defined fields in the object.", "properties": { "eventname": { @@ -303,7 +312,6 @@ }, "ChannelHangupRequest": { "id": "ChannelHangupRequest", - "extends": "Event", "description": "A hangup was requested on the channel.", "properties": { "cause": { @@ -323,7 +331,6 @@ }, "ChannelVarset": { "id": "ChannelVarset", - "extends": "Event", "description": "Channel variable changed.", "properties": { "variable": { @@ -345,7 +352,6 @@ }, "EndpointStateChange": { "id": "EndpointStateChange", - "extends": "Event", "description": "Endpoint state changed.", "properties": { "endpoint": { @@ -356,7 +362,6 @@ }, "StasisEnd": { "id": "StasisEnd", - "extends": "Event", "description": "Notification that a channel has left a Stasis appliction.", "properties": { "channel": { @@ -367,7 +372,6 @@ }, "StasisStart": { "id": "StasisStart", - "extends": "Event", "description": "Notification that a channel has entered a Stasis appliction.", "properties": { "args": {