]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
message & stasis/messaging: make text message variables work in ARI
authorKevin Harwell <kharwell@digium.com>
Fri, 28 Feb 2020 18:53:40 +0000 (12:53 -0600)
committerKevin Harwell <kharwell@digium.com>
Mon, 2 Mar 2020 18:11:59 +0000 (12:11 -0600)
When a text message was received any associated variable was not written to
the ARI TextMessageReceived event. This occurred because Asterisk only wrote
out "send" variables. However, even those "send" variables would fail ARI
validation due to a TextMessageVariable formatting bug.

Since it seems the TextMessageReceived event has never been able to include
actual variables it was decided to remove the TextMessageVariable object type
from ARI, and simply return a JSON object of key/value pairs for variables.
This aligns more with how the ARI sendMessage handles variables, and other
places in ARI.

That being the case, and since this is technically an API breaking change (no
one should really be affected since things never really worked) the ARI version
was updated to reflect that.

ASTERISK-28755 #close

Change-Id: Ia6051c01a53b30cf7edef84c27df4ed4479b8b6f

doc/UPGRADE-staging/ari_messaging.txt [new file with mode: 0644]
include/asterisk/message.h
main/message.c
res/ari/ari_model_validators.c
res/ari/ari_model_validators.h
res/stasis/messaging.c
rest-api/api-docs/endpoints.json
rest-api/resources.json

diff --git a/doc/UPGRADE-staging/ari_messaging.txt b/doc/UPGRADE-staging/ari_messaging.txt
new file mode 100644 (file)
index 0000000..199a8a2
--- /dev/null
@@ -0,0 +1,26 @@
+Subject: ARI
+Subject: res_stasis
+
+The "TextMessageReceived" event used to include a list of "TextMessageVariable"
+objects as part of its output. Due to a couple of bugs in Asterisk a list of
+received variables was never included even if ones were available. However,
+variables set to send would be (which they should have not been), but would
+fail validation due to the bad formatting.
+
+So basically there was no way to get a "TextMessageReceived" event with
+variables. Due to this the API has changed. The "TextMessageVariable" object
+no longer exists. "TextMessageReceived" now returns a JSON object of key/value
+pairs. So for instance instead of a list of "TextMessageVariable" objects:
+
+[ TextMessageVariable, TextMessageVariable, TextMessageVariable]
+
+where a TextMessageVariable was supposed to be:
+
+{ "key": "<var name>", "value":, "<var value>" }
+
+The output is now just:
+
+{ "<var name>": "<var value>" }
+
+This aligns more with how variables are specified when sending a message, as
+well as other variable lists in ARI.
index 826fa0ac3aeffc6bd32cca44ef0c91020be94ff7..f5b7a7528da6d014e85ae39cdda6d274c34ab2fa 100644 (file)
@@ -396,6 +396,19 @@ struct ast_msg_var_iterator *ast_msg_var_iterator_init(const struct ast_msg *msg
  */
 int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value);
 
+/*!
+ * \brief Get the next variable name and value that was set on a received message
+ * \param msg The message with the variables
+ * \param iter An iterator created with ast_msg_var_iterator_init
+ * \param name A pointer to the name result pointer
+ * \param value A pointer to the value result pointer
+ *
+ * \retval 0 No more entries
+ * \retval 1 Valid entry
+ */
+int ast_msg_var_iterator_next_received(const struct ast_msg *msg,
+       struct ast_msg_var_iterator *iter, const char **name, const char **value);
+
 /*!
  * \brief Destroy a message variable iterator
  * \param iter Iterator to be destroyed
index 0543bf4aac91d1ffd12447e3194adc6d4ca47d18..128f4d9106a07aa900cc8aaeeb3ccf19d9a54510 100644 (file)
@@ -629,7 +629,9 @@ struct ast_msg_var_iterator *ast_msg_var_iterator_init(const struct ast_msg *msg
        return iter;
 }
 
-int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
+static int ast_msg_var_iterator_get_next(const struct ast_msg *msg,
+       struct ast_msg_var_iterator *iter, const char **name, const char **value,
+       unsigned int send)
 {
        struct msg_data *data;
 
@@ -637,8 +639,8 @@ int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iter
                return 0;
        }
 
-       /* Skip any that aren't marked for sending out */
-       while ((data = ao2_iterator_next(&iter->iter)) && !data->send) {
+       /* Skip any that we're told to */
+       while ((data = ao2_iterator_next(&iter->iter)) && (data->send != send)) {
                ao2_ref(data, -1);
        }
 
@@ -646,7 +648,7 @@ int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iter
                return 0;
        }
 
-       if (data->send) {
+       if (data->send == send) {
                *name = data->name;
                *value = data->value;
        }
@@ -658,6 +660,17 @@ int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iter
        return 1;
 }
 
+int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
+{
+       return ast_msg_var_iterator_get_next(msg, iter, name, value, 1);
+}
+
+int ast_msg_var_iterator_next_received(const struct ast_msg *msg,
+         struct ast_msg_var_iterator *iter, const char **name, const char **value)
+{
+       return ast_msg_var_iterator_get_next(msg, iter, name, value, 0);
+}
+
 void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter)
 {
        ao2_cleanup(iter->current_used);
index 8e23d6bff618c2ef84e6f7054b30fade2cf0f597..75bd983a98d9983b04a36a3e093da811fa23d799 100644 (file)
@@ -941,9 +941,8 @@ int ast_ari_validate_text_message(struct ast_json *json)
                } else
                if (strcmp("variables", ast_json_object_iter_key(iter)) == 0) {
                        int prop_is_valid;
-                       prop_is_valid = ast_ari_validate_list(
-                               ast_json_object_iter_value(iter),
-                               ast_ari_validate_text_message_variable);
+                       prop_is_valid = ast_ari_validate_object(
+                               ast_json_object_iter_value(iter));
                        if (!prop_is_valid) {
                                ast_log(LOG_ERROR, "ARI TextMessage field variables failed validation\n");
                                res = 0;
@@ -980,60 +979,6 @@ ari_validator ast_ari_validate_text_message_fn(void)
        return ast_ari_validate_text_message;
 }
 
-int ast_ari_validate_text_message_variable(struct ast_json *json)
-{
-       int res = 1;
-       struct ast_json_iter *iter;
-       int has_key = 0;
-       int has_value = 0;
-
-       for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
-               if (strcmp("key", ast_json_object_iter_key(iter)) == 0) {
-                       int prop_is_valid;
-                       has_key = 1;
-                       prop_is_valid = ast_ari_validate_string(
-                               ast_json_object_iter_value(iter));
-                       if (!prop_is_valid) {
-                               ast_log(LOG_ERROR, "ARI TextMessageVariable field key failed validation\n");
-                               res = 0;
-                       }
-               } else
-               if (strcmp("value", ast_json_object_iter_key(iter)) == 0) {
-                       int prop_is_valid;
-                       has_value = 1;
-                       prop_is_valid = ast_ari_validate_string(
-                               ast_json_object_iter_value(iter));
-                       if (!prop_is_valid) {
-                               ast_log(LOG_ERROR, "ARI TextMessageVariable field value failed validation\n");
-                               res = 0;
-                       }
-               } else
-               {
-                       ast_log(LOG_ERROR,
-                               "ARI TextMessageVariable has undocumented field %s\n",
-                               ast_json_object_iter_key(iter));
-                       res = 0;
-               }
-       }
-
-       if (!has_key) {
-               ast_log(LOG_ERROR, "ARI TextMessageVariable missing required field key\n");
-               res = 0;
-       }
-
-       if (!has_value) {
-               ast_log(LOG_ERROR, "ARI TextMessageVariable missing required field value\n");
-               res = 0;
-       }
-
-       return res;
-}
-
-ari_validator ast_ari_validate_text_message_variable_fn(void)
-{
-       return ast_ari_validate_text_message_variable;
-}
-
 int ast_ari_validate_caller_id(struct ast_json *json)
 {
        int res = 1;
index 64e11c0498a1d6c0b1dfaf2db84afd1462b6d47d..a8b24ba0e8b69c533bbdb41aba434ee6a03cc200 100644 (file)
@@ -388,24 +388,6 @@ int ast_ari_validate_text_message(struct ast_json *json);
  */
 ari_validator ast_ari_validate_text_message_fn(void);
 
-/*!
- * \brief Validator for TextMessageVariable.
- *
- * A key/value pair variable in a text message.
- *
- * \param json JSON object to validate.
- * \returns True (non-zero) if valid.
- * \returns False (zero) if invalid.
- */
-int ast_ari_validate_text_message_variable(struct ast_json *json);
-
-/*!
- * \brief Function pointer to ast_ari_validate_text_message_variable().
- *
- * See \ref ast_ari_model_validators.h for more details.
- */
-ari_validator ast_ari_validate_text_message_variable_fn(void);
-
 /*!
  * \brief Validator for CallerID.
  *
@@ -1480,10 +1462,7 @@ ari_validator ast_ari_validate_application_fn(void);
  * - body: string (required)
  * - from: string (required)
  * - to: string (required)
- * - variables: List[TextMessageVariable]
- * TextMessageVariable
- * - key: string (required)
- * - value: string (required)
+ * - variables: object
  * CallerID
  * - name: string (required)
  * - number: string (required)
index 4a86d5875578bf5f754f5d9422c8db5f5dd3e4a4..4df10cc7479fc8ac1727a0f23cb2f9dc62771f94 100644 (file)
@@ -264,23 +264,20 @@ static struct ast_json *msg_to_json(struct ast_msg *msg)
                return NULL;
        }
 
-       json_vars = ast_json_array_create();
+       json_vars = ast_json_object_create();
        if (!json_vars) {
                ast_msg_var_iterator_destroy(it_vars);
                return NULL;
        }
 
-       while (ast_msg_var_iterator_next(msg, it_vars, &name, &value)) {
-               struct ast_json *json_tuple;
-
-               json_tuple = ast_json_pack("{s: s}", name, value);
-               if (!json_tuple) {
+       while (ast_msg_var_iterator_next_received(msg, it_vars, &name, &value)) {
+               struct ast_json *json_val = ast_json_string_create(value);
+               if (!json_val || ast_json_object_set(json_vars, name, json_val)) {
                        ast_json_unref(json_vars);
                        ast_msg_var_iterator_destroy(it_vars);
                        return NULL;
                }
 
-               ast_json_array_append(json_vars, json_tuple);
                ast_msg_var_unref_current(it_vars);
        }
        ast_msg_var_iterator_destroy(it_vars);
index 13a5beda91b7cb792f2f527a211fa761948a115f..65152950a8201d4670d198e6f108f116e07e8e52 100644 (file)
                                }
                        }
                },
-               "TextMessageVariable": {
-                       "id": "TextMessageVariable",
-                       "description": "A key/value pair variable in a text message.",
-                       "properties": {
-                               "key": {
-                                       "type": "string",
-                                       "description": "A unique key identifying the variable.",
-                                       "required": true
-                               },
-                               "value": {
-                                       "type": "string",
-                                       "description": "The value of the variable.",
-                                       "required": true
-                               }
-                       }
-               },
                "TextMessage": {
                        "id": "TextMessage",
                        "description": "A text message.",
                                        "required": true
                                },
                                "variables": {
-                                       "type": "List[TextMessageVariable]",
-                                       "description": "Technology specific key/value pairs associated with the message.",
+                                       "type": "object",
+                                       "description": "Technology specific key/value pairs (JSON object) associated with the message.",
                                        "required": false
                                }
                        }
index 20d58f99154e9cce97ca55a65785d70244f6e917..63dbe9bfcb3a60b8fcc4aa0b253a4e6b7a38ee88 100644 (file)
@@ -2,7 +2,7 @@
        "_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.",
        "_author": "David M. Lee, II <dlee@digium.com>",
        "_svn_revision": "$Revision$",
-       "apiVersion": "1.10.2",
+       "apiVersion": "1.11.2",
        "swaggerVersion": "1.1",
        "basePath": "http://localhost:8088/ari",
        "apis": [