mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
The Swagger 1.2 specification for type extension ended up being
slightly different than my proposal. Instead of putting an 'extends' field on the subtype, the base type has a 'subTypes' field, which is a list of the subTypes. Given that its a messaging model and not an object model, kinda makes sense. This patch changes the events.json api-doc, and the python translators to take the new format into account. Other changes that are in Swagger 1.2 were not adopted, since the spec is still in flux, and could change before it's finalized. A summary of changes to the Swagger-1.2 spec can be found at https://github.com/wordnik/swagger-core/wiki/1.2-transition. (closes issue ASTERISK-22440) Review: https://reviewboard.asterisk.org/r/2909/ ........ Merged revisions 401701 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@401834 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -57,11 +57,11 @@ int ast_ari_validate_{{c_id}}(struct ast_json *json)
|
|||||||
if (strcmp("{{id}}", discriminator) == 0) {
|
if (strcmp("{{id}}", discriminator) == 0) {
|
||||||
/* Self type; fall through */
|
/* Self type; fall through */
|
||||||
} else
|
} else
|
||||||
{{#subtypes}}
|
{{#all_subtypes}}
|
||||||
if (strcmp("{{id}}", discriminator) == 0) {
|
if (strcmp("{{id}}", discriminator) == 0) {
|
||||||
return ast_ari_validate_{{c_id}}(json);
|
return ast_ari_validate_{{c_id}}(json);
|
||||||
} else
|
} else
|
||||||
{{/subtypes}}
|
{{/all_subtypes}}
|
||||||
{
|
{
|
||||||
ast_log(LOG_ERROR, "ARI {{id}} has undocumented subtype %s\n",
|
ast_log(LOG_ERROR, "ARI {{id}} has undocumented subtype %s\n",
|
||||||
discriminator);
|
discriminator);
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
{{#models}}
|
{{#models}}
|
||||||
h1. {{id}}
|
h1. {{id}}
|
||||||
{{#extends}}Base type: [{{extends}}|#{{extends}}]{{/extends}}
|
{{#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}}
|
||||||
|
|
||||||
{{{wiki_description}}}
|
{{{wiki_description}}}
|
||||||
|
@@ -33,8 +33,8 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
# I'm not quite sure what was in Swagger 1.2, but apparently I missed it
|
# We don't fully support Swagger 1.2, but we need it for subtyping
|
||||||
SWAGGER_VERSIONS = ["1.1", "1.3"]
|
SWAGGER_VERSIONS = ["1.1", "1.2"]
|
||||||
|
|
||||||
SWAGGER_PRIMITIVES = [
|
SWAGGER_PRIMITIVES = [
|
||||||
'void',
|
'void',
|
||||||
@@ -479,13 +479,13 @@ class Model(Stringify):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.id = None
|
self.id = None
|
||||||
self.extends = None
|
self.subtypes = []
|
||||||
self.extends_type = None
|
self.__subtype_types = []
|
||||||
self.notes = None
|
self.notes = None
|
||||||
self.description = None
|
self.description = None
|
||||||
self.__properties = None
|
self.__properties = None
|
||||||
self.__discriminator = None
|
self.__discriminator = None
|
||||||
self.__subtypes = []
|
self.__extends_type = None
|
||||||
|
|
||||||
def load(self, id, model_json, processor, context):
|
def load(self, id, model_json, processor, context):
|
||||||
context = context.next_stack(model_json, 'id')
|
context = context.next_stack(model_json, 'id')
|
||||||
@@ -494,9 +494,9 @@ class Model(Stringify):
|
|||||||
self.id = model_json.get('id')
|
self.id = model_json.get('id')
|
||||||
if id != self.id:
|
if id != self.id:
|
||||||
raise SwaggerError("Model id doesn't match name", context)
|
raise SwaggerError("Model id doesn't match name", context)
|
||||||
self.extends = model_json.get('extends')
|
self.subtypes = model_json.get('subTypes') or []
|
||||||
if self.extends and context.version_less_than("1.3"):
|
if self.subtypes and context.version_less_than("1.2"):
|
||||||
raise SwaggerError("Type extension support added in Swagger 1.3",
|
raise SwaggerError("Type extension support added in Swagger 1.2",
|
||||||
context)
|
context)
|
||||||
self.description = model_json.get('description')
|
self.description = model_json.get('description')
|
||||||
props = model_json.get('properties').items() or []
|
props = model_json.get('properties').items() or []
|
||||||
@@ -507,8 +507,8 @@ class Model(Stringify):
|
|||||||
discriminator = model_json.get('discriminator')
|
discriminator = model_json.get('discriminator')
|
||||||
|
|
||||||
if discriminator:
|
if discriminator:
|
||||||
if context.version_less_than("1.3"):
|
if context.version_less_than("1.2"):
|
||||||
raise SwaggerError("Discriminator support added in Swagger 1.3",
|
raise SwaggerError("Discriminator support added in Swagger 1.2",
|
||||||
context)
|
context)
|
||||||
|
|
||||||
discr_props = [p for p in self.__properties if p.name == discriminator]
|
discr_props = [p for p in self.__properties if p.name == discriminator]
|
||||||
@@ -526,43 +526,42 @@ class Model(Stringify):
|
|||||||
processor.process_model(self, context)
|
processor.process_model(self, context)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def add_subtype(self, subtype):
|
def extends(self):
|
||||||
"""Add subtype to this model.
|
return self.__extends_type and self.__extends_type.id
|
||||||
|
|
||||||
@param subtype: Model instance for the subtype.
|
|
||||||
"""
|
|
||||||
self.__subtypes.append(subtype)
|
|
||||||
|
|
||||||
def set_extends_type(self, extends_type):
|
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):
|
def discriminator(self):
|
||||||
"""Returns the discriminator, digging through base types if needed.
|
"""Returns the discriminator, digging through base types if needed.
|
||||||
"""
|
"""
|
||||||
return self.__discriminator or \
|
return self.__discriminator or \
|
||||||
self.extends_type and self.extends_type.discriminator()
|
self.__extends_type and self.__extends_type.discriminator()
|
||||||
|
|
||||||
def properties(self):
|
def properties(self):
|
||||||
base_props = []
|
base_props = []
|
||||||
if self.extends_type:
|
if self.__extends_type:
|
||||||
base_props = self.extends_type.properties()
|
base_props = self.__extends_type.properties()
|
||||||
return base_props + self.__properties
|
return base_props + self.__properties
|
||||||
|
|
||||||
def has_properties(self):
|
def has_properties(self):
|
||||||
return len(self.properties()) > 0
|
return len(self.properties()) > 0
|
||||||
|
|
||||||
def subtypes(self):
|
def all_subtypes(self):
|
||||||
"""Returns the full list of all subtypes.
|
"""Returns the full list of all subtypes, including sub-subtypes.
|
||||||
"""
|
"""
|
||||||
res = self.__subtypes + \
|
res = self.__subtype_types + \
|
||||||
[subsubtypes for subtype in self.__subtypes
|
[subsubtypes for subtype in self.__subtype_types
|
||||||
for subsubtypes in subtype.subtypes()]
|
for subsubtypes in subtype.all_subtypes()]
|
||||||
return sorted(res, key=lambda m: m.id)
|
return sorted(res, key=lambda m: m.id)
|
||||||
|
|
||||||
def has_subtypes(self):
|
def has_subtypes(self):
|
||||||
"""Returns True if type has any subtypes.
|
"""Returns True if type has any subtypes.
|
||||||
"""
|
"""
|
||||||
return len(self.subtypes()) > 0
|
return len(self.subtypes) > 0
|
||||||
|
|
||||||
|
|
||||||
class ApiDeclaration(Stringify):
|
class ApiDeclaration(Stringify):
|
||||||
@@ -641,13 +640,16 @@ class ApiDeclaration(Stringify):
|
|||||||
# Now link all base/extended types
|
# Now link all base/extended types
|
||||||
model_dict = dict((m.id, m) for m in self.models)
|
model_dict = dict((m.id, m) for m in self.models)
|
||||||
for m in self.models:
|
for m in self.models:
|
||||||
if m.extends:
|
def link_subtype(name):
|
||||||
extends_type = model_dict.get(m.extends)
|
res = model_dict.get(subtype)
|
||||||
if not extends_type:
|
if not res:
|
||||||
raise SwaggerError("%s extends non-existing model %s",
|
raise SwaggerError("%s has non-existing subtype %s",
|
||||||
m.id, m.extends)
|
m.id, name)
|
||||||
extends_type.add_subtype(m)
|
res.set_extends_type(m)
|
||||||
m.set_extends_type(extends_type)
|
return res;
|
||||||
|
if m.subtypes:
|
||||||
|
m.set_subtype_types([
|
||||||
|
link_subtype(subtype) for subtype in m.subtypes])
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
"_author": "David M. Lee, II <dlee@digium.com>",
|
"_author": "David M. Lee, II <dlee@digium.com>",
|
||||||
"_svn_revision": "$Revision$",
|
"_svn_revision": "$Revision$",
|
||||||
"apiVersion": "0.0.1",
|
"apiVersion": "0.0.1",
|
||||||
"swaggerVersion": "1.3",
|
"swaggerVersion": "1.2",
|
||||||
"basePath": "http://localhost:8088/stasis",
|
"basePath": "http://localhost:8088/stasis",
|
||||||
"resourcePath": "/api-docs/events.{format}",
|
"resourcePath": "/api-docs/events.{format}",
|
||||||
"apis": [
|
"apis": [
|
||||||
@@ -43,11 +43,14 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"description": "Indicates the type of this message."
|
"description": "Indicates the type of this message."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"subTypes": [
|
||||||
|
"MissingParams",
|
||||||
|
"Event"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"MissingParams": {
|
"MissingParams": {
|
||||||
"id": "MissingParams",
|
"id": "MissingParams",
|
||||||
"extends": "Message",
|
|
||||||
"description": "Error event sent when required params are missing.",
|
"description": "Error event sent when required params are missing.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"params": {
|
"params": {
|
||||||
@@ -59,7 +62,6 @@
|
|||||||
},
|
},
|
||||||
"Event": {
|
"Event": {
|
||||||
"id": "Event",
|
"id": "Event",
|
||||||
"extends": "Message",
|
|
||||||
"description": "Base type for asynchronous events from Asterisk.",
|
"description": "Base type for asynchronous events from Asterisk.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"application": {
|
"application": {
|
||||||
@@ -72,11 +74,32 @@
|
|||||||
"description": "Time at which this event was created.",
|
"description": "Time at which this event was created.",
|
||||||
"required": false
|
"required": false
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"subTypes": [
|
||||||
|
"PlaybackStarted",
|
||||||
|
"PlaybackFinished",
|
||||||
|
"ApplicationReplaced",
|
||||||
|
"BridgeCreated",
|
||||||
|
"BridgeDestroyed",
|
||||||
|
"BridgeMerged",
|
||||||
|
"ChannelCreated",
|
||||||
|
"ChannelDestroyed",
|
||||||
|
"ChannelEnteredBridge",
|
||||||
|
"ChannelLeftBridge",
|
||||||
|
"ChannelStateChange",
|
||||||
|
"ChannelDtmfReceived",
|
||||||
|
"ChannelDialplan",
|
||||||
|
"ChannelCallerId",
|
||||||
|
"ChannelUserevent",
|
||||||
|
"ChannelHangupRequest",
|
||||||
|
"ChannelVarset",
|
||||||
|
"EndpointStateChange",
|
||||||
|
"StasisEnd",
|
||||||
|
"StasisStart"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"PlaybackStarted": {
|
"PlaybackStarted": {
|
||||||
"id": "PlaybackStarted",
|
"id": "PlaybackStarted",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Event showing the start of a media playback operation.",
|
"description": "Event showing the start of a media playback operation.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"playback": {
|
"playback": {
|
||||||
@@ -88,7 +111,6 @@
|
|||||||
},
|
},
|
||||||
"PlaybackFinished": {
|
"PlaybackFinished": {
|
||||||
"id": "PlaybackFinished",
|
"id": "PlaybackFinished",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Event showing the completion of a media playback operation.",
|
"description": "Event showing the completion of a media playback operation.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"playback": {
|
"playback": {
|
||||||
@@ -100,13 +122,11 @@
|
|||||||
},
|
},
|
||||||
"ApplicationReplaced": {
|
"ApplicationReplaced": {
|
||||||
"id": "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.",
|
"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": {}
|
"properties": {}
|
||||||
},
|
},
|
||||||
"BridgeCreated": {
|
"BridgeCreated": {
|
||||||
"id": "BridgeCreated",
|
"id": "BridgeCreated",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a bridge has been created.",
|
"description": "Notification that a bridge has been created.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bridge": {
|
"bridge": {
|
||||||
@@ -117,7 +137,6 @@
|
|||||||
},
|
},
|
||||||
"BridgeDestroyed": {
|
"BridgeDestroyed": {
|
||||||
"id": "BridgeDestroyed",
|
"id": "BridgeDestroyed",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a bridge has been destroyed.",
|
"description": "Notification that a bridge has been destroyed.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bridge": {
|
"bridge": {
|
||||||
@@ -128,7 +147,6 @@
|
|||||||
},
|
},
|
||||||
"BridgeMerged": {
|
"BridgeMerged": {
|
||||||
"id": "BridgeMerged",
|
"id": "BridgeMerged",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that one bridge has merged into another.",
|
"description": "Notification that one bridge has merged into another.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bridge": {
|
"bridge": {
|
||||||
@@ -143,7 +161,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelCreated": {
|
"ChannelCreated": {
|
||||||
"id": "ChannelCreated",
|
"id": "ChannelCreated",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a channel has been created.",
|
"description": "Notification that a channel has been created.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"channel": {
|
"channel": {
|
||||||
@@ -154,7 +171,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelDestroyed": {
|
"ChannelDestroyed": {
|
||||||
"id": "ChannelDestroyed",
|
"id": "ChannelDestroyed",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a channel has been destroyed.",
|
"description": "Notification that a channel has been destroyed.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"cause": {
|
"cause": {
|
||||||
@@ -175,7 +191,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelEnteredBridge": {
|
"ChannelEnteredBridge": {
|
||||||
"id": "ChannelEnteredBridge",
|
"id": "ChannelEnteredBridge",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a channel has entered a bridge.",
|
"description": "Notification that a channel has entered a bridge.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bridge": {
|
"bridge": {
|
||||||
@@ -189,7 +204,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelLeftBridge": {
|
"ChannelLeftBridge": {
|
||||||
"id": "ChannelLeftBridge",
|
"id": "ChannelLeftBridge",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a channel has left a bridge.",
|
"description": "Notification that a channel has left a bridge.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bridge": {
|
"bridge": {
|
||||||
@@ -204,7 +218,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelStateChange": {
|
"ChannelStateChange": {
|
||||||
"id": "ChannelStateChange",
|
"id": "ChannelStateChange",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification of a channel's state change.",
|
"description": "Notification of a channel's state change.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"channel": {
|
"channel": {
|
||||||
@@ -215,7 +228,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelDtmfReceived": {
|
"ChannelDtmfReceived": {
|
||||||
"id": "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",
|
"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": {
|
"properties": {
|
||||||
"digit": {
|
"digit": {
|
||||||
@@ -237,7 +249,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelDialplan": {
|
"ChannelDialplan": {
|
||||||
"id": "ChannelDialplan",
|
"id": "ChannelDialplan",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Channel changed location in the dialplan.",
|
"description": "Channel changed location in the dialplan.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"channel": {
|
"channel": {
|
||||||
@@ -259,7 +270,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelCallerId": {
|
"ChannelCallerId": {
|
||||||
"id": "ChannelCallerId",
|
"id": "ChannelCallerId",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Channel changed Caller ID.",
|
"description": "Channel changed Caller ID.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"caller_presentation": {
|
"caller_presentation": {
|
||||||
@@ -281,7 +291,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelUserevent": {
|
"ChannelUserevent": {
|
||||||
"id": "ChannelUserevent",
|
"id": "ChannelUserevent",
|
||||||
"extends": "Event",
|
|
||||||
"description": "User-generated event with additional user-defined fields in the object.",
|
"description": "User-generated event with additional user-defined fields in the object.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"eventname": {
|
"eventname": {
|
||||||
@@ -303,7 +312,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelHangupRequest": {
|
"ChannelHangupRequest": {
|
||||||
"id": "ChannelHangupRequest",
|
"id": "ChannelHangupRequest",
|
||||||
"extends": "Event",
|
|
||||||
"description": "A hangup was requested on the channel.",
|
"description": "A hangup was requested on the channel.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"cause": {
|
"cause": {
|
||||||
@@ -323,7 +331,6 @@
|
|||||||
},
|
},
|
||||||
"ChannelVarset": {
|
"ChannelVarset": {
|
||||||
"id": "ChannelVarset",
|
"id": "ChannelVarset",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Channel variable changed.",
|
"description": "Channel variable changed.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"variable": {
|
"variable": {
|
||||||
@@ -345,7 +352,6 @@
|
|||||||
},
|
},
|
||||||
"EndpointStateChange": {
|
"EndpointStateChange": {
|
||||||
"id": "EndpointStateChange",
|
"id": "EndpointStateChange",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Endpoint state changed.",
|
"description": "Endpoint state changed.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"endpoint": {
|
"endpoint": {
|
||||||
@@ -356,7 +362,6 @@
|
|||||||
},
|
},
|
||||||
"StasisEnd": {
|
"StasisEnd": {
|
||||||
"id": "StasisEnd",
|
"id": "StasisEnd",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a channel has left a Stasis appliction.",
|
"description": "Notification that a channel has left a Stasis appliction.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"channel": {
|
"channel": {
|
||||||
@@ -367,7 +372,6 @@
|
|||||||
},
|
},
|
||||||
"StasisStart": {
|
"StasisStart": {
|
||||||
"id": "StasisStart",
|
"id": "StasisStart",
|
||||||
"extends": "Event",
|
|
||||||
"description": "Notification that a channel has entered a Stasis appliction.",
|
"description": "Notification that a channel has entered a Stasis appliction.",
|
||||||
"properties": {
|
"properties": {
|
||||||
"args": {
|
"args": {
|
||||||
|
Reference in New Issue
Block a user