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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">stasis / manager / ari: Better filter messages.<br><br>Previously both AMI and ARI used a default route on<br>their stasis message router to handle some of the<br>messages for publishing out their respective<br>connection. This caused messages to be given to<br>their subscription that could not be formatted<br>into AMI or JSON.<br><br>This change adds an API call to the stasis message<br>router which allows a default route to be set as well<br>as formatters that the default route is expecting.<br>This allows both AMI and ARI to specify that their<br>default route only wants messages of their given<br>formatter. By doing so stasis can more intelligently<br>filter at publishing time so that they do not receive<br>messages which will not be turned into AMI or JSON.<br><br>ASTERISK-28244<br><br>Change-Id: I65272819a53ce99f869181d1d370da559a7d1703<br>---<br>M include/asterisk/stasis_message_router.h<br>M main/manager.c<br>M main/manager_channels.c<br>M main/stasis_message_router.c<br>M res/stasis/app.c<br>5 files changed, 68 insertions(+), 16 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/stasis_message_router.h b/include/asterisk/stasis_message_router.h</span><br><span>index fefbea0..e9e2c62 100644</span><br><span>--- a/include/asterisk/stasis_message_router.h</span><br><span>+++ b/include/asterisk/stasis_message_router.h</span><br><span>@@ -238,7 +238,7 @@</span><br><span>  * \brief Sets the default route of a router.</span><br><span>  *</span><br><span>  * \param router Router to set the default route of.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param callback Callback to forard messages which otherwise have no home.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param callback Callback to forward messages which otherwise have no home.</span><br><span>  * \param data Data pointer to pass to \a callback.</span><br><span>  *</span><br><span>  * \retval 0 on success</span><br><span>@@ -255,6 +255,27 @@</span><br><span>                                  void *data);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Sets the default route of a router with formatters.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param router Router to set the default route of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param callback Callback to forward messages which otherwise have no home.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param data Data pointer to pass to \a callback.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param formatters A bitmap of \ref stasis_subscription_message_formatters we wish to receive.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.26.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.3.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note If formatters are specified then the message router will remain in a selective</span><br><span style="color: hsl(120, 100%, 40%);">+ * filtering state. Any explicit routes will receive messages of their message type and</span><br><span style="color: hsl(120, 100%, 40%);">+ * the default callback will only receive messages that have one of the given formatters.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Explicit routes will not be filtered according to the given formatters.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void stasis_message_router_set_formatters_default(struct stasis_message_router *router,</span><br><span style="color: hsl(120, 100%, 40%);">+      stasis_subscription_cb callback,</span><br><span style="color: hsl(120, 100%, 40%);">+      void *data,</span><br><span style="color: hsl(120, 100%, 40%);">+   enum stasis_subscription_message_formatters formatters);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Indicate to a message router that we are interested in messages with one or more formatters.</span><br><span>  *</span><br><span>  * The formatters are passed on to the underlying subscription.</span><br><span>diff --git a/main/manager.c b/main/manager.c</span><br><span>index 0469a73..85d5b18 100644</span><br><span>--- a/main/manager.c</span><br><span>+++ b/main/manager.c</span><br><span>@@ -8904,8 +8904,8 @@</span><br><span>      stasis_message_router_set_congestion_limits(stasis_router, -1,</span><br><span>               6 * AST_TASKPROCESSOR_HIGH_WATER_LEVEL);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    res |= stasis_message_router_set_default(stasis_router,</span><br><span style="color: hsl(0, 100%, 40%);">-         manager_default_msg_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+        stasis_message_router_set_formatters_default(stasis_router,</span><br><span style="color: hsl(120, 100%, 40%);">+           manager_default_msg_cb, NULL, STASIS_SUBSCRIPTION_FORMATTER_AMI);</span><br><span> </span><br><span>        res |= stasis_message_router_add(stasis_router,</span><br><span>              ast_manager_get_generic_type(), manager_generic_msg_cb, NULL);</span><br><span>diff --git a/main/manager_channels.c b/main/manager_channels.c</span><br><span>index ac09d42..94d33b8 100644</span><br><span>--- a/main/manager_channels.c</span><br><span>+++ b/main/manager_channels.c</span><br><span>@@ -1272,6 +1272,10 @@</span><br><span> </span><br><span>         ast_register_cleanup(manager_channels_shutdown);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  /* The snapshot type has a special handler as it can result in multiple</span><br><span style="color: hsl(120, 100%, 40%);">+        * manager events being queued due to aspects of the snapshot itself</span><br><span style="color: hsl(120, 100%, 40%);">+   * changing.</span><br><span style="color: hsl(120, 100%, 40%);">+   */</span><br><span>  ret |= stasis_message_router_add_cache_update(message_router,</span><br><span>                ast_channel_snapshot_type(), channel_snapshot_update, NULL);</span><br><span> </span><br><span>diff --git a/main/stasis_message_router.c b/main/stasis_message_router.c</span><br><span>index f320c34..41ff794 100644</span><br><span>--- a/main/stasis_message_router.c</span><br><span>+++ b/main/stasis_message_router.c</span><br><span>@@ -388,18 +388,33 @@</span><br><span>        stasis_subscription_cb callback,</span><br><span>     void *data)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+      stasis_message_router_set_formatters_default(router, callback, data, STASIS_SUBSCRIPTION_FORMATTER_NONE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* While this implementation can never fail, it used to be able to */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void stasis_message_router_set_formatters_default(struct stasis_message_router *router,</span><br><span style="color: hsl(120, 100%, 40%);">+       stasis_subscription_cb callback,</span><br><span style="color: hsl(120, 100%, 40%);">+      void *data,</span><br><span style="color: hsl(120, 100%, 40%);">+   enum stasis_subscription_message_formatters formatters)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span>   ast_assert(router != NULL);</span><br><span>  ast_assert(callback != NULL);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     stasis_subscription_accept_formatters(router->subscription, formatters);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        ao2_lock(router);</span><br><span>    router->default_route.callback = callback;</span><br><span>        router->default_route.data = data;</span><br><span>        ao2_unlock(router);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- stasis_subscription_set_filter(router->subscription, STASIS_SUBSCRIPTION_FILTER_FORCED_NONE);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* While this implementation can never fail, it used to be able to */</span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (formatters == STASIS_SUBSCRIPTION_FORMATTER_NONE) {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Formatters govern what messages the default callback get, so it is only if none is</span><br><span style="color: hsl(120, 100%, 40%);">+          * specified that we accept all messages regardless.</span><br><span style="color: hsl(120, 100%, 40%);">+           */</span><br><span style="color: hsl(120, 100%, 40%);">+           stasis_subscription_set_filter(router->subscription, STASIS_SUBSCRIPTION_FILTER_FORCED_NONE);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span> }</span><br><span> </span><br><span> void stasis_message_router_accept_formatters(struct stasis_message_router *router,</span><br><span>diff --git a/res/stasis/app.c b/res/stasis/app.c</span><br><span>index 18ac7d6..3a917db 100644</span><br><span>--- a/res/stasis/app.c</span><br><span>+++ b/res/stasis/app.c</span><br><span>@@ -330,16 +330,25 @@</span><br><span>        ast_channel_unref(chan);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void sub_subscription_change_handler(void *data, struct stasis_subscription *sub,</span><br><span style="color: hsl(120, 100%, 40%);">+   struct stasis_message *message)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct stasis_app *app = data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (stasis_subscription_final_message(sub, message)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ao2_cleanup(app);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void sub_default_handler(void *data, struct stasis_subscription *sub,</span><br><span>       struct stasis_message *message)</span><br><span> {</span><br><span>         struct stasis_app *app = data;</span><br><span>       struct ast_json *json;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (stasis_subscription_final_message(sub, message)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ao2_cleanup(app);</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%);">+     /* The dial type can be converted to JSON so it will always be passed</span><br><span style="color: hsl(120, 100%, 40%);">+  * here.</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span>  if (stasis_message_type(message) == ast_channel_dial_type()) {</span><br><span>               call_forwarded_handler(app, message);</span><br><span>        }</span><br><span>@@ -843,7 +852,7 @@</span><br><span>      }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void bridge_default_handler(void *data, struct stasis_subscription *sub,</span><br><span style="color: hsl(120, 100%, 40%);">+static void bridge_subscription_change_handler(void *data, struct stasis_subscription *sub,</span><br><span>       struct stasis_message *message)</span><br><span> {</span><br><span>         struct stasis_app *app = data;</span><br><span>@@ -970,8 +979,8 @@</span><br><span>         res |= stasis_message_router_add(app->bridge_router,</span><br><span>              ast_attended_transfer_type(), bridge_attended_transfer_handler, app);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       res |= stasis_message_router_set_default(app->bridge_router,</span><br><span style="color: hsl(0, 100%, 40%);">-         bridge_default_handler, app);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= stasis_message_router_add(app->bridge_router,</span><br><span style="color: hsl(120, 100%, 40%);">+               stasis_subscription_change_type(), bridge_subscription_change_handler, app);</span><br><span> </span><br><span>     if (res != 0) {</span><br><span>              return NULL;</span><br><span>@@ -993,8 +1002,11 @@</span><br><span>         res |= stasis_message_router_add_cache_update(app->router,</span><br><span>                ast_endpoint_snapshot_type(), sub_endpoint_update_handler, app);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    res |= stasis_message_router_set_default(app->router,</span><br><span style="color: hsl(0, 100%, 40%);">-                sub_default_handler, app);</span><br><span style="color: hsl(120, 100%, 40%);">+    res |= stasis_message_router_add(app->router,</span><br><span style="color: hsl(120, 100%, 40%);">+              stasis_subscription_change_type(), sub_subscription_change_handler, app);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   stasis_message_router_set_formatters_default(app->router,</span><br><span style="color: hsl(120, 100%, 40%);">+          sub_default_handler, app, STASIS_SUBSCRIPTION_FORMATTER_JSON);</span><br><span> </span><br><span>   if (res != 0) {</span><br><span>              return NULL;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10877">change 10877</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/10877"/><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-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I65272819a53ce99f869181d1d370da559a7d1703 </div>
<div style="display:none"> Gerrit-Change-Number: 10877 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Joshua C. Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation (1000185) </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua C. Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>