[Asterisk-code-review] ARI: Added new functionality to unload a single module. (asterisk[13])

Mark Michelson asteriskteam at digium.com
Tue Jul 14 12:27:22 CDT 2015


Mark Michelson has submitted this change and it was merged.

Change subject: ARI: Added new functionality to unload a single module.
......................................................................


ARI: Added new functionality to unload a single module.

An http request can be sent to unload an Asterisk module. If the
module can not be unloaded or is already unloaded, an error response
will be returned.

The command "curl -v -u user:pass -X DELETE 'http://localhost:8088
/ari/asterisk/modules/{moduleName}'" (or something similar, depending
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 unloaded through http requests

ASTERISK-25173

Change-Id: I535a95f5676deb02651522761ecbdc0b00b5ac57
---
M CHANGES
M res/ari/resource_asterisk.c
M res/ari/resource_asterisk.h
M res/res_ari_asterisk.c
M rest-api/api-docs/asterisk.json
5 files changed, 130 insertions(+), 1 deletion(-)

Approvals:
  Mark Michelson: Looks good to me, approved
  Anonymous Coward #1000019: Verified
  Ashley Sanders: Looks good to me, but someone else must approve



diff --git a/CHANGES b/CHANGES
index 9fa9e2a..1e4e113 100644
--- a/CHANGES
+++ b/CHANGES
@@ -24,7 +24,8 @@
 ------------------
  * 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.
+   can be also be retrieved. Individual modules can be loaded to Asterisk, as
+   well as unloaded.
 
 res_pjsip
 ------------------
diff --git a/res/ari/resource_asterisk.c b/res/ari/resource_asterisk.c
index 2422798..4c2948d 100644
--- a/res/ari/resource_asterisk.c
+++ b/res/ari/resource_asterisk.c
@@ -295,6 +295,34 @@
 	ast_ari_response_no_content(response);
 }
 
+void ast_ari_asterisk_unload_module(struct ast_variable *headers,
+	struct ast_ari_asterisk_unload_module_args *args,
+	struct ast_ari_response *response)
+{
+	int unload_result;
+	enum ast_module_unload_mode unload_mode = AST_FORCE_FIRM;
+
+	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;
+	}
+
+	unload_result = ast_unload_resource(args->module_name, unload_mode);
+
+	if (unload_result != 0) {
+		ast_ari_response_error(
+			response, 409, "Conflict",
+			"Module could not be unloaded");
+		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 5846a71..5e3ff9b 100644
--- a/res/ari/resource_asterisk.h
+++ b/res/ari/resource_asterisk.h
@@ -104,6 +104,19 @@
  * \param[out] response HTTP response
  */
 void ast_ari_asterisk_load_module(struct ast_variable *headers, struct ast_ari_asterisk_load_module_args *args, struct ast_ari_response *response);
+/*! Argument struct for ast_ari_asterisk_unload_module() */
+struct ast_ari_asterisk_unload_module_args {
+	/*! Module's name */
+	const char *module_name;
+};
+/*!
+ * \brief Unload an Asterisk module.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \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_get_global_var() */
 struct ast_ari_asterisk_get_global_var_args {
 	/*! The variable to get */
diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c
index 771a448..161c643 100644
--- a/res/res_ari_asterisk.c
+++ b/res/res_ari_asterisk.c
@@ -379,6 +379,66 @@
 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_unload_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_unload_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_unload_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 unloaded. */
+		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)
@@ -585,6 +645,7 @@
 	.callbacks = {
 		[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,
 	},
 	.num_children = 0,
 	.children = {  }
diff --git a/rest-api/api-docs/asterisk.json b/rest-api/api-docs/asterisk.json
index dcbfb2c..28badce 100644
--- a/rest-api/api-docs/asterisk.json
+++ b/rest-api/api-docs/asterisk.json
@@ -101,6 +101,32 @@
 							"reason": "Module could not be loaded."
 						}
 					]
+				},
+				{
+					"httpMethod": "DELETE",
+					"summary": "Unload an Asterisk module.",
+					"nickname": "unloadModule",
+					"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 unloaded."
+						}
+					]
 				}
 			]
 		},

-- 
To view, visit https://gerrit.asterisk.org/808
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I535a95f5676deb02651522761ecbdc0b00b5ac57
Gerrit-PatchSet: 5
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Benjamin Keith Ford <bford at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Ashley Sanders <asanders at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>



More information about the asterisk-code-review mailing list