summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Ford <bford@digium.com>2015-07-14 13:12:32 -0500
committerBenjamin Ford <bford@digium.com>2015-07-14 13:15:39 -0500
commit1aafadf8148a7cf66f73beeb6fe711d98b678fc5 (patch)
treecf4d8e057b7c39fba6cc4706bd00c01cd62a5dad
parent9dcae23cfceedece83568d2194df00ca62f7d53c (diff)
ARI: Added new functionality to reload a single module.
An http request can be sent to reload an Asterisk module. If the module can not be reloaded or is not already loaded, an error response will be returned. The command "curl -v -u user:pass -X PUT 'http://localhost:8088 /ari/asterisk/modules/{moduleName}'" (or something similar, based on configuration) can be run in the terminal to access this new functionality. For more information, see: https://wiki.asterisk.org/wiki.display/~bford/Asterisk+ARI+Resource * Added new ARI functionality * Asterisk modules can be reloaded through http requests ASTERISK-25173 Change-Id: I289188bcae182b2083bdbd9ebfffd50b62f58ae1
-rw-r--r--CHANGES2
-rw-r--r--include/asterisk/ari.h5
-rw-r--r--res/ari/resource_asterisk.c50
-rw-r--r--res/ari/resource_asterisk.h13
-rw-r--r--res/res_ari.c7
-rw-r--r--res/res_ari_asterisk.c61
-rw-r--r--rest-api/api-docs/asterisk.json26
7 files changed, 163 insertions, 1 deletions
diff --git a/CHANGES b/CHANGES
index 1e4e11374..31813cdfe 100644
--- a/CHANGES
+++ b/CHANGES
@@ -25,7 +25,7 @@ ARI
* A new feature has been added that enables the retrieval of modules and
module information through an HTTP request. Information on a single module
can be also be retrieved. Individual modules can be loaded to Asterisk, as
- well as unloaded.
+ well as unloaded and reloaded.
res_pjsip
------------------
diff --git a/include/asterisk/ari.h b/include/asterisk/ari.h
index 00769eea5..c3df46a2b 100644
--- a/include/asterisk/ari.h
+++ b/include/asterisk/ari.h
@@ -225,6 +225,11 @@ void ast_ari_response_ok(struct ast_ari_response *response,
void ast_ari_response_no_content(struct ast_ari_response *response);
/*!
+ * \brief Fill in a <tt>Accepted</tt> (202) \a ast_ari_response.
+ */
+void ast_ari_response_accepted(struct ast_ari_response *response);
+
+/*!
* \brief Fill in a <tt>Created</tt> (201) \a ast_ari_response.
* \param response Response to fill in.
* \param url URL to the created resource.
diff --git a/res/ari/resource_asterisk.c b/res/ari/resource_asterisk.c
index 4c2948d2b..1b9bf2120 100644
--- a/res/ari/resource_asterisk.c
+++ b/res/ari/resource_asterisk.c
@@ -323,6 +323,56 @@ void ast_ari_asterisk_unload_module(struct ast_variable *headers,
ast_ari_response_no_content(response);
}
+void ast_ari_asterisk_reload_module(struct ast_variable *headers,
+ struct ast_ari_asterisk_reload_module_args *args,
+ struct ast_ari_response *response)
+{
+ enum ast_module_reload_result reload_result;
+
+ ast_assert(response != NULL);
+
+ if (!ast_module_check(args->module_name)) {
+ ast_ari_response_error(
+ response, 404, "Not Found",
+ "Module not found in running modules");
+ return;
+ }
+
+ reload_result = ast_module_reload(args->module_name);
+
+ if (reload_result == AST_MODULE_RELOAD_NOT_FOUND) {
+ ast_ari_response_error(
+ response, 404, "Not Found",
+ "Module could not be found");
+ return;
+ } else if (reload_result == AST_MODULE_RELOAD_ERROR) {
+ ast_ari_response_error(
+ response, 409, "Conflict",
+ "An unknown error occurred while reloading the module");
+ return;
+ } else if (reload_result == AST_MODULE_RELOAD_IN_PROGRESS) {
+ ast_ari_response_error(
+ response, 409, "Conflict",
+ "Another reload is currently in progress");
+ return;
+ } else if (reload_result == AST_MODULE_RELOAD_UNINITIALIZED) {
+ ast_ari_response_error(
+ response, 409, "Conflict",
+ "Module has not been initialized");
+ return;
+ } else if (reload_result == AST_MODULE_RELOAD_NOT_IMPLEMENTED) {
+ ast_ari_response_error(
+ response, 409, "Conflict",
+ "Module does not support reloading");
+ return;
+ } else if (reload_result == AST_MODULE_RELOAD_QUEUED) {
+ ast_ari_response_accepted(response);
+ return;
+ }
+
+ ast_ari_response_no_content(response);
+}
+
void ast_ari_asterisk_get_global_var(struct ast_variable *headers,
struct ast_ari_asterisk_get_global_var_args *args,
struct ast_ari_response *response)
diff --git a/res/ari/resource_asterisk.h b/res/ari/resource_asterisk.h
index 5e3ff9b15..574d947e4 100644
--- a/res/ari/resource_asterisk.h
+++ b/res/ari/resource_asterisk.h
@@ -117,6 +117,19 @@ struct ast_ari_asterisk_unload_module_args {
* \param[out] response HTTP response
*/
void ast_ari_asterisk_unload_module(struct ast_variable *headers, struct ast_ari_asterisk_unload_module_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_asterisk_reload_module() */
+struct ast_ari_asterisk_reload_module_args {
+ /*! Module's name */
+ const char *module_name;
+};
+/*!
+ * \brief Reload an Asterisk module.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_asterisk_reload_module(struct ast_variable *headers, struct ast_ari_asterisk_reload_module_args *args, struct ast_ari_response *response);
/*! Argument struct for ast_ari_asterisk_get_global_var() */
struct ast_ari_asterisk_get_global_var_args {
/*! The variable to get */
diff --git a/res/res_ari.c b/res/res_ari.c
index 28f9be18b..761c2dd39 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -284,6 +284,13 @@ void ast_ari_response_no_content(struct ast_ari_response *response)
response->response_text = "No Content";
}
+void ast_ari_response_accepted(struct ast_ari_response *response)
+{
+ response->message = ast_json_null();
+ response->response_code = 202;
+ response->response_text = "Accepted";
+}
+
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
{
response->message = ast_json_ref(oom_json);
diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c
index 161c64322..ec8b05e52 100644
--- a/res/res_ari_asterisk.c
+++ b/res/res_ari_asterisk.c
@@ -439,6 +439,66 @@ static void ast_ari_asterisk_unload_module_cb(
fin: __attribute__((unused))
return;
}
+/*!
+ * \brief Parameter parsing callback for /asterisk/modules/{moduleName}.
+ * \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_reload_module_cb(
+ struct ast_tcptls_session_instance *ser,
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_ari_asterisk_reload_module_args args = {};
+ struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "moduleName") == 0) {
+ args.module_name = (i->value);
+ } else
+ {}
+ }
+ ast_ari_asterisk_reload_module(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 */
+ case 404: /* Module not found in running modules. */
+ case 409: /* Module could not be reloaded. */
+ is_valid = 1;
+ break;
+ default:
+ if (200 <= code && code <= 299) {
+ is_valid = ast_ari_validate_void(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /asterisk/modules/{moduleName}\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /asterisk/modules/{moduleName}\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+ return;
+}
int ast_ari_asterisk_get_global_var_parse_body(
struct ast_json *body,
struct ast_ari_asterisk_get_global_var_args *args)
@@ -646,6 +706,7 @@ static struct stasis_rest_handlers asterisk_modules_moduleName = {
[AST_HTTP_GET] = ast_ari_asterisk_get_module_cb,
[AST_HTTP_POST] = ast_ari_asterisk_load_module_cb,
[AST_HTTP_DELETE] = ast_ari_asterisk_unload_module_cb,
+ [AST_HTTP_PUT] = ast_ari_asterisk_reload_module_cb,
},
.num_children = 0,
.children = { }
diff --git a/rest-api/api-docs/asterisk.json b/rest-api/api-docs/asterisk.json
index 28badce80..c6968a5ba 100644
--- a/rest-api/api-docs/asterisk.json
+++ b/rest-api/api-docs/asterisk.json
@@ -127,6 +127,32 @@
"reason": "Module could not be unloaded."
}
]
+ },
+ {
+ "httpMethod": "PUT",
+ "summary": "Reload an Asterisk module.",
+ "nickname": "reloadModule",
+ "responseClass": "void",
+ "parameters": [
+ {
+ "name": "moduleName",
+ "description": "Module's name",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 404,
+ "reason": "Module not found in running modules."
+ },
+ {
+ "code": 409,
+ "reason": "Module could not be reloaded."
+ }
+ ]
}
]
},