<p>George Joseph <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13077">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Benjamin Keith Ford: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  George Joseph: Approved for Submit

</div><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;"><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 0fd2d69..81a902c 100644</span><br><span>--- a/res/ari/resource_channels.c</span><br><span>+++ b/res/ari/resource_channels.c</span><br><span>@@ -2064,7 +2064,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>@@ -2093,43 +2092,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 27d9deb..f938e14 100644</span><br><span>--- a/res/res_ari_channels.c</span><br><span>+++ b/res/res_ari_channels.c</span><br><span>@@ -2918,7 +2918,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 53e6e9d..94afb27 100644</span><br><span>--- a/rest-api/api-docs/channels.json</span><br><span>+++ b/rest-api/api-docs/channels.json</span><br><span>@@ -1765,7 +1765,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>@@ -2166,27 +2166,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/+/13077">change 13077</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/+/13077"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 17 </div>
<div style="display:none"> Gerrit-Change-Id: If280094debd35102cf21e0a31a5e0846fec14af9 </div>
<div style="display:none"> Gerrit-Change-Number: 13077 </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-Reviewer: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>