<p>George Joseph has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13076">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">ExternalMedia: Change return object from ExternalMedia to Channel<br><br>When we created the External Media addition to ARI we created an<br>ExternalMedia object to be returned from the channels/externalMedia<br>REST endpoint. This object contained the channel object that was<br>created plus local_address and local_port attributes (which are<br>also in the Channel variables). At the time, we thought that<br>creating an ExternalMedia object would give us more flexibility<br>in the future but as we created the sample speech to text<br>application, we discovered that it doesn't work so well with ARI<br>client libraries that a) don't have the ExternalMedia object<br>defined and/or b) can't promote the embedded channel structure<br>to a first-class Channel object.<br><br>This change causes the channels/externalMedia REST endpoint to<br>return a Channel object (like channels/create and channels/originate)<br>instead of the ExternalMedia object.<br><br>Change-Id: If280094debd35102cf21e0a31a5e0846fec14af9<br>---<br>M res/ari/ari_model_validators.c<br>M res/ari/ari_model_validators.h<br>M res/ari/resource_channels.c<br>M res/res_ari_channels.c<br>M rest-api/api-docs/channels.json<br>5 files changed, 3 insertions(+), 136 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/76/13076/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c</span><br><span>index 3d63f53..8910bbb 100644</span><br><span>--- a/res/ari/ari_model_validators.c</span><br><span>+++ b/res/ari/ari_model_validators.c</span><br><span>@@ -1385,62 +1385,6 @@</span><br><span> return ast_ari_validate_dialplan_cep;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int ast_ari_validate_external_media(struct ast_json *json)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int res = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_json_iter *iter;</span><br><span style="color: hsl(0, 100%, 40%);">- int has_channel = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (strcmp("channel", ast_json_object_iter_key(iter)) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- int prop_is_valid;</span><br><span style="color: hsl(0, 100%, 40%);">- has_channel = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- prop_is_valid = ast_ari_validate_channel(</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_iter_value(iter));</span><br><span style="color: hsl(0, 100%, 40%);">- if (!prop_is_valid) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "ARI ExternalMedia field channel failed validation\n");</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- if (strcmp("local_address", ast_json_object_iter_key(iter)) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- int prop_is_valid;</span><br><span style="color: hsl(0, 100%, 40%);">- prop_is_valid = ast_ari_validate_string(</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_iter_value(iter));</span><br><span style="color: hsl(0, 100%, 40%);">- if (!prop_is_valid) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "ARI ExternalMedia field local_address failed validation\n");</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- if (strcmp("local_port", ast_json_object_iter_key(iter)) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- int prop_is_valid;</span><br><span style="color: hsl(0, 100%, 40%);">- prop_is_valid = ast_ari_validate_int(</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_iter_value(iter));</span><br><span style="color: hsl(0, 100%, 40%);">- if (!prop_is_valid) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "ARI ExternalMedia field local_port failed validation\n");</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">- "ARI ExternalMedia has undocumented field %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_iter_key(iter));</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!has_channel) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "ARI ExternalMedia missing required field channel\n");</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return res;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ari_validator ast_ari_validate_external_media_fn(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return ast_ari_validate_external_media;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> int ast_ari_validate_rtpstat(struct ast_json *json)</span><br><span> {</span><br><span> int res = 1;</span><br><span>diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h</span><br><span>index 53a8573..f9285b4 100644</span><br><span>--- a/res/ari/ari_model_validators.h</span><br><span>+++ b/res/ari/ari_model_validators.h</span><br><span>@@ -478,24 +478,6 @@</span><br><span> ari_validator ast_ari_validate_dialplan_cep_fn(void);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Validator for ExternalMedia.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * ExternalMedia session.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \param json JSON object to validate.</span><br><span style="color: hsl(0, 100%, 40%);">- * \returns True (non-zero) if valid.</span><br><span style="color: hsl(0, 100%, 40%);">- * \returns False (zero) if invalid.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-int ast_ari_validate_external_media(struct ast_json *json);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Function pointer to ast_ari_validate_external_media().</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * See \ref ast_ari_model_validators.h for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-ari_validator ast_ari_validate_external_media_fn(void);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span> * \brief Validator for RTPstat.</span><br><span> *</span><br><span> * A statistics of a RTP.</span><br><span>@@ -1540,10 +1522,6 @@</span><br><span> * - context: string (required)</span><br><span> * - exten: string (required)</span><br><span> * - priority: long (required)</span><br><span style="color: hsl(0, 100%, 40%);">- * ExternalMedia</span><br><span style="color: hsl(0, 100%, 40%);">- * - channel: Channel (required)</span><br><span style="color: hsl(0, 100%, 40%);">- * - local_address: string</span><br><span style="color: hsl(0, 100%, 40%);">- * - local_port: int</span><br><span> * RTPstat</span><br><span> * - channel_uniqueid: string (required)</span><br><span> * - local_maxjitter: double</span><br><span>diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c</span><br><span>index ec0960d..944c94c 100644</span><br><span>--- a/res/ari/resource_channels.c</span><br><span>+++ b/res/ari/resource_channels.c</span><br><span>@@ -2060,7 +2060,6 @@</span><br><span> size_t endpoint_len;</span><br><span> char *endpoint;</span><br><span> struct ast_channel *chan;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_json *json_chan;</span><br><span> struct varshead *vars;</span><br><span> </span><br><span> endpoint_len = strlen("UnicastRTP/") + strlen(args->external_host) + 1;</span><br><span>@@ -2089,43 +2088,10 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * At this point, response->message contains a channel object so we</span><br><span style="color: hsl(0, 100%, 40%);">- * need to save it then create a new ExternalMedia object and put the</span><br><span style="color: hsl(0, 100%, 40%);">- * channel in it.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- json_chan = response->message;</span><br><span style="color: hsl(0, 100%, 40%);">- response->message = ast_json_object_create();</span><br><span style="color: hsl(0, 100%, 40%);">- if (!response->message) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_unref(chan);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_unref(json_chan);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_ari_response_alloc_failed(response);</span><br><span style="color: hsl(0, 100%, 40%);">- return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_set(response->message, "channel", json_chan);</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * At the time the channel snapshot was taken the channel variables might</span><br><span style="color: hsl(0, 100%, 40%);">- * not have been set so we try to grab them directly from the channel.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span> ast_channel_lock(chan);</span><br><span> vars = ast_channel_varshead(chan);</span><br><span> if (vars && !AST_LIST_EMPTY(vars)) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_var_t *variables;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Put them all on the channel object */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_set(json_chan, "channelvars", ast_json_channel_vars(vars));</span><br><span style="color: hsl(0, 100%, 40%);">- /* Grab out the local address and port */</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_TRAVERSE(vars, variables, entries) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcmp("UNICASTRTP_LOCAL_ADDRESS", ast_var_name(variables))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_set(response->message, "local_address",</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_string_create(ast_var_value(variables)));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- else if (!strcmp("UNICASTRTP_LOCAL_PORT", ast_var_name(variables))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_object_set(response->message, "local_port",</span><br><span style="color: hsl(0, 100%, 40%);">- ast_json_integer_create(strtol(ast_var_value(variables), NULL, 10)));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_json_object_set(response->message, "channelvars", ast_json_channel_vars(vars));</span><br><span> }</span><br><span> ast_channel_unlock(chan);</span><br><span> ast_channel_unref(chan);</span><br><span>diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c</span><br><span>index fe3a96c..bb153c9 100644</span><br><span>--- a/res/res_ari_channels.c</span><br><span>+++ b/res/res_ari_channels.c</span><br><span>@@ -2911,7 +2911,7 @@</span><br><span> break;</span><br><span> default:</span><br><span> if (200 <= code && code <= 299) {</span><br><span style="color: hsl(0, 100%, 40%);">- is_valid = ast_ari_validate_external_media(</span><br><span style="color: hsl(120, 100%, 40%);">+ is_valid = ast_ari_validate_channel(</span><br><span> response->message);</span><br><span> } else {</span><br><span> ast_log(LOG_ERROR, "Invalid error response %d for /channels/externalMedia\n", code);</span><br><span>diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json</span><br><span>index 6d964d2..366fec8 100644</span><br><span>--- a/rest-api/api-docs/channels.json</span><br><span>+++ b/rest-api/api-docs/channels.json</span><br><span>@@ -1758,7 +1758,7 @@</span><br><span> "summary": "Start an External Media session.",</span><br><span> "notes": "Create a channel to an External Media source/sink.",</span><br><span> "nickname": "externalMedia",</span><br><span style="color: hsl(0, 100%, 40%);">- "responseClass": "ExternalMedia",</span><br><span style="color: hsl(120, 100%, 40%);">+ "responseClass": "Channel",</span><br><span> "parameters": [</span><br><span> {</span><br><span> "name": "channelId",</span><br><span>@@ -2159,27 +2159,6 @@</span><br><span> "description": "Channel variables"</span><br><span> }</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- "ExternalMedia": {</span><br><span style="color: hsl(0, 100%, 40%);">- "id": "ExternalMedia",</span><br><span style="color: hsl(0, 100%, 40%);">- "description": "ExternalMedia session.",</span><br><span style="color: hsl(0, 100%, 40%);">- "properties": {</span><br><span style="color: hsl(0, 100%, 40%);">- "channel": {</span><br><span style="color: hsl(0, 100%, 40%);">- "required": true,</span><br><span style="color: hsl(0, 100%, 40%);">- "type": "Channel",</span><br><span style="color: hsl(0, 100%, 40%);">- "description": "The Asterisk channel representing the external media"</span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- "local_address": {</span><br><span style="color: hsl(0, 100%, 40%);">- "required": false,</span><br><span style="color: hsl(0, 100%, 40%);">- "type": "string",</span><br><span style="color: hsl(0, 100%, 40%);">- "description": "The local ip address used" </span><br><span style="color: hsl(0, 100%, 40%);">- },</span><br><span style="color: hsl(0, 100%, 40%);">- "local_port": {</span><br><span style="color: hsl(0, 100%, 40%);">- "required": false,</span><br><span style="color: hsl(0, 100%, 40%);">- "type": "int",</span><br><span style="color: hsl(0, 100%, 40%);">- "description": "The local ip port used" </span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> }</span><br><span> }</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/13076">change 13076</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/13076"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: If280094debd35102cf21e0a31a5e0846fec14af9 </div>
<div style="display:none"> Gerrit-Change-Number: 13076 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>