Added ARI resource /ari/asterisk/ping
authorsungtae kim <sungtae@messagebird.com>
Mon, 28 Jan 2019 23:21:28 +0000 (00:21 +0100)
committerJoshua Colp <jcolp@digium.com>
Wed, 30 Jan 2019 12:51:03 +0000 (12:51 +0000)
Added ARI resource.
GET /ari/asterisk/ping : It returns "pong" message with timestamp
and asterisk id. It would be useful for simple heath check.

Change-Id: I8d24e1dcc96f60f73437c68d9463ed746f688b29

res/ari/ari_model_validators.c
res/ari/ari_model_validators.h
res/ari/resource_asterisk.c
res/ari/resource_asterisk.h
res/res_ari_asterisk.c
rest-api/api-docs/asterisk.json

index ea5a885..a06a1f5 100644 (file)
@@ -91,6 +91,76 @@ ari_validator ast_ari_validate_asterisk_info_fn(void)
        return ast_ari_validate_asterisk_info;
 }
 
+int ast_ari_validate_asterisk_ping(struct ast_json *json)
+{
+       int res = 1;
+       struct ast_json_iter *iter;
+       int has_asterisk_id = 0;
+       int has_ping = 0;
+       int has_timestamp = 0;
+
+       for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+               if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+                       int prop_is_valid;
+                       has_asterisk_id = 1;
+                       prop_is_valid = ast_ari_validate_string(
+                               ast_json_object_iter_value(iter));
+                       if (!prop_is_valid) {
+                               ast_log(LOG_ERROR, "ARI AsteriskPing field asterisk_id failed validation\n");
+                               res = 0;
+                       }
+               } else
+               if (strcmp("ping", ast_json_object_iter_key(iter)) == 0) {
+                       int prop_is_valid;
+                       has_ping = 1;
+                       prop_is_valid = ast_ari_validate_string(
+                               ast_json_object_iter_value(iter));
+                       if (!prop_is_valid) {
+                               ast_log(LOG_ERROR, "ARI AsteriskPing field ping failed validation\n");
+                               res = 0;
+                       }
+               } else
+               if (strcmp("timestamp", ast_json_object_iter_key(iter)) == 0) {
+                       int prop_is_valid;
+                       has_timestamp = 1;
+                       prop_is_valid = ast_ari_validate_string(
+                               ast_json_object_iter_value(iter));
+                       if (!prop_is_valid) {
+                               ast_log(LOG_ERROR, "ARI AsteriskPing field timestamp failed validation\n");
+                               res = 0;
+                       }
+               } else
+               {
+                       ast_log(LOG_ERROR,
+                               "ARI AsteriskPing has undocumented field %s\n",
+                               ast_json_object_iter_key(iter));
+                       res = 0;
+               }
+       }
+
+       if (!has_asterisk_id) {
+               ast_log(LOG_ERROR, "ARI AsteriskPing missing required field asterisk_id\n");
+               res = 0;
+       }
+
+       if (!has_ping) {
+               ast_log(LOG_ERROR, "ARI AsteriskPing missing required field ping\n");
+               res = 0;
+       }
+
+       if (!has_timestamp) {
+               ast_log(LOG_ERROR, "ARI AsteriskPing missing required field timestamp\n");
+               res = 0;
+       }
+
+       return res;
+}
+
+ari_validator ast_ari_validate_asterisk_ping_fn(void)
+{
+       return ast_ari_validate_asterisk_ping;
+}
+
 int ast_ari_validate_build_info(struct ast_json *json)
 {
        int res = 1;
index 3c501cf..ab0b2f6 100644 (file)
@@ -170,6 +170,24 @@ int ast_ari_validate_asterisk_info(struct ast_json *json);
 ari_validator ast_ari_validate_asterisk_info_fn(void);
 
 /*!
+ * \brief Validator for AsteriskPing.
+ *
+ * Asterisk ping information
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_asterisk_ping(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_asterisk_ping().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_asterisk_ping_fn(void);
+
+/*!
  * \brief Validator for BuildInfo.
  *
  * Info about how Asterisk was built
@@ -1391,6 +1409,10 @@ ari_validator ast_ari_validate_application_fn(void);
  * - config: ConfigInfo
  * - status: StatusInfo
  * - system: SystemInfo
+ * AsteriskPing
+ * - asterisk_id: string (required)
+ * - ping: string (required)
+ * - timestamp: string (required)
  * BuildInfo
  * - date: string (required)
  * - kernel: string (required)
index 5c6a35a..4e3dea7 100644 (file)
@@ -631,6 +631,24 @@ void ast_ari_asterisk_reload_module(struct ast_variable *headers,
        ast_ari_response_no_content(response);
 }
 
+void ast_ari_asterisk_ping(struct ast_variable *headers,
+       struct ast_ari_asterisk_ping_args *args,
+       struct ast_ari_response *response)
+{
+       struct ast_json *json;
+       char eid[20];
+
+       ast_assert(response != NULL);
+
+       json = ast_json_pack("{s: s, s: o, s: s}",
+                       "ping", "pong",
+                       "timestamp", ast_json_timeval(ast_tvnow(), NULL),
+                       "asterisk_id", ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)
+                       );
+
+       ast_ari_response_ok(response, json);
+}
+
 /*!
  * \brief Process logger information and append to a json array
  * \param channel Resource logger channel name path
index a4a7da0..5b2d494 100644 (file)
@@ -131,6 +131,17 @@ int ast_ari_asterisk_get_info_parse_body(
  * \param[out] response HTTP response
  */
 void ast_ari_asterisk_get_info(struct ast_variable *headers, struct ast_ari_asterisk_get_info_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_asterisk_ping() */
+struct ast_ari_asterisk_ping_args {
+};
+/*!
+ * \brief Response pong message.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_asterisk_ping(struct ast_variable *headers, struct ast_ari_asterisk_ping_args *args, struct ast_ari_response *response);
 /*! Argument struct for ast_ari_asterisk_list_modules() */
 struct ast_ari_asterisk_list_modules_args {
 };
index e143a7f..a077548 100644 (file)
@@ -396,6 +396,56 @@ fin: __attribute__((unused))
        return;
 }
 /*!
+ * \brief Parameter parsing callback for /asterisk/ping.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_asterisk_ping_cb(
+       struct ast_tcptls_session_instance *ser,
+       struct ast_variable *get_params, struct ast_variable *path_vars,
+       struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
+{
+       struct ast_ari_asterisk_ping_args args = {};
+#if defined(AST_DEVMODE)
+       int is_valid;
+       int code;
+#endif /* AST_DEVMODE */
+
+       ast_ari_asterisk_ping(headers, &args, response);
+#if defined(AST_DEVMODE)
+       code = response->response_code;
+
+       switch (code) {
+       case 0: /* Implementation is still a stub, or the code wasn't set */
+               is_valid = response->message == NULL;
+               break;
+       case 500: /* Internal Server Error */
+       case 501: /* Not Implemented */
+               is_valid = 1;
+               break;
+       default:
+               if (200 <= code && code <= 299) {
+                       is_valid = ast_ari_validate_asterisk_ping(
+                               response->message);
+               } else {
+                       ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/ping\n", code);
+                       is_valid = 0;
+               }
+       }
+
+       if (!is_valid) {
+               ast_log(LOG_ERROR, "Response validation failed for /asterisk/ping\n");
+               ast_ari_response_error(response, 500,
+                       "Internal Server Error", "Response validation failed");
+       }
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+       return;
+}
+/*!
  * \brief Parameter parsing callback for /asterisk/modules.
  * \param get_params GET parameters in the HTTP request.
  * \param path_vars Path variables extracted from the request.
@@ -1142,6 +1192,15 @@ static struct stasis_rest_handlers asterisk_info = {
        .children = {  }
 };
 /*! \brief REST handler for /api-docs/asterisk.json */
+static struct stasis_rest_handlers asterisk_ping = {
+       .path_segment = "ping",
+       .callbacks = {
+               [AST_HTTP_GET] = ast_ari_asterisk_ping_cb,
+       },
+       .num_children = 0,
+       .children = {  }
+};
+/*! \brief REST handler for /api-docs/asterisk.json */
 static struct stasis_rest_handlers asterisk_modules_moduleName = {
        .path_segment = "moduleName",
        .is_wildcard = 1,
@@ -1207,8 +1266,8 @@ static struct stasis_rest_handlers asterisk = {
        .path_segment = "asterisk",
        .callbacks = {
        },
-       .num_children = 5,
-       .children = { &asterisk_config,&asterisk_info,&asterisk_modules,&asterisk_logging,&asterisk_variable, }
+       .num_children = 6,
+       .children = { &asterisk_config,&asterisk_info,&asterisk_ping,&asterisk_modules,&asterisk_logging,&asterisk_variable, }
 };
 
 static int unload_module(void)
index f40bf5c..841e6cd 100644 (file)
                        ]
                },
                {
+                       "path": "/asterisk/ping",
+                       "description": "Asterisk ping",
+                       "operations": [
+                               {
+                                       "httpMethod": "GET",
+                                       "summary": "Response pong message.",
+                                       "nickname": "ping",
+                                       "responseClass": "AsteriskPing"
+                               }
+                       ]
+               },
+               {
                        "path": "/asterisk/modules",
                        "description": "Asterisk modules",
                        "operations": [
                                }
                        }
                },
+               "AsteriskPing": {
+                       "id": "AsteriskPing",
+                       "description": "Asterisk ping information",
+                       "properties": {
+                               "asterisk_id": {
+                                       "required": true,
+                                       "type": "string",
+                                       "description": "Asterisk id info"
+                               },
+                               "ping": {
+                                       "required": true,
+                                       "type": "string",
+                                       "description": "Always string value is pong"
+                               },
+                               "timestamp": {
+                                       "required": true,
+                                       "type": "string",
+                                       "description": "The timestamp string of request received time"
+                               }
+                       }
+               },
                "Module": {
                        "id": "Module",
                        "description": "Details of an Asterisk module",