123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2012 - 2013, Digium, Inc.
- *
- * David M. Lee, II <dlee@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
- /*! \file
- *
- * \brief /api-docs/endpoints.{format} implementation- Endpoint resources
- *
- * \author David M. Lee, II <dlee@digium.com>
- */
- #include "asterisk.h"
- ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- #include "resource_endpoints.h"
- #include "asterisk/astobj2.h"
- #include "asterisk/stasis.h"
- #include "asterisk/stasis_app.h"
- #include "asterisk/stasis_endpoints.h"
- #include "asterisk/channel.h"
- #include "asterisk/message.h"
- void ast_ari_endpoints_list(struct ast_variable *headers,
- struct ast_ari_endpoints_list_args *args,
- struct ast_ari_response *response)
- {
- RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
- RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
- struct ao2_iterator i;
- void *obj;
- cache = ast_endpoint_cache();
- if (!cache) {
- ast_ari_response_error(
- response, 500, "Internal Server Error",
- "Message bus not initialized");
- return;
- }
- ao2_ref(cache, +1);
- snapshots = stasis_cache_dump(cache, ast_endpoint_snapshot_type());
- if (!snapshots) {
- ast_ari_response_alloc_failed(response);
- return;
- }
- json = ast_json_array_create();
- if (!json) {
- ast_ari_response_alloc_failed(response);
- return;
- }
- i = ao2_iterator_init(snapshots, 0);
- while ((obj = ao2_iterator_next(&i))) {
- RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup);
- struct ast_endpoint_snapshot *snapshot = stasis_message_data(msg);
- struct ast_json *json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
- if (!json_endpoint || ast_json_array_append(json, json_endpoint)) {
- ao2_iterator_destroy(&i);
- ast_ari_response_alloc_failed(response);
- return;
- }
- }
- ao2_iterator_destroy(&i);
- ast_ari_response_ok(response, ast_json_ref(json));
- }
- void ast_ari_endpoints_list_by_tech(struct ast_variable *headers,
- struct ast_ari_endpoints_list_by_tech_args *args,
- struct ast_ari_response *response)
- {
- RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup);
- RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
- RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
- struct ast_endpoint *tech_endpoint;
- struct ao2_iterator i;
- void *obj;
- tech_endpoint = ast_endpoint_find_by_id(args->tech);
- if (!tech_endpoint) {
- ast_ari_response_error(response, 404, "Not Found",
- "No Endpoints found - invalid tech %s", args->tech);
- return;
- }
- ao2_ref(tech_endpoint, -1);
- cache = ast_endpoint_cache();
- if (!cache) {
- ast_ari_response_error(
- response, 500, "Internal Server Error",
- "Message bus not initialized");
- return;
- }
- ao2_ref(cache, +1);
- snapshots = stasis_cache_dump(cache, ast_endpoint_snapshot_type());
- if (!snapshots) {
- ast_ari_response_alloc_failed(response);
- return;
- }
- json = ast_json_array_create();
- if (!json) {
- ast_ari_response_alloc_failed(response);
- return;
- }
- i = ao2_iterator_init(snapshots, 0);
- while ((obj = ao2_iterator_next(&i))) {
- RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup);
- struct ast_endpoint_snapshot *snapshot = stasis_message_data(msg);
- struct ast_json *json_endpoint;
- int r;
- if (strcasecmp(args->tech, snapshot->tech) != 0) {
- continue;
- }
- json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
- if (!json_endpoint) {
- continue;
- }
- r = ast_json_array_append(
- json, json_endpoint);
- if (r != 0) {
- ao2_iterator_destroy(&i);
- ast_ari_response_alloc_failed(response);
- return;
- }
- }
- ao2_iterator_destroy(&i);
- ast_ari_response_ok(response, ast_json_ref(json));
- }
- void ast_ari_endpoints_get(struct ast_variable *headers,
- struct ast_ari_endpoints_get_args *args,
- struct ast_ari_response *response)
- {
- struct ast_json *json;
- RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup);
- snapshot = ast_endpoint_latest_snapshot(args->tech, args->resource);
- if (!snapshot) {
- ast_ari_response_error(response, 404, "Not Found",
- "Endpoint not found");
- return;
- }
- json = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
- if (!json) {
- ast_ari_response_alloc_failed(response);
- return;
- }
- ast_ari_response_ok(response, json);
- }
- static void send_message(const char *to, const char *from, const char *body, struct ast_variable *variables, struct ast_ari_response *response)
- {
- struct ast_variable *current;
- struct ast_msg *msg;
- int res = 0;
- if (ast_strlen_zero(to)) {
- ast_ari_response_error(response, 400, "Bad Request",
- "To must be specified");
- return;
- }
- msg = ast_msg_alloc();
- if (!msg) {
- ast_ari_response_alloc_failed(response);
- return;
- }
- res |= ast_msg_set_from(msg, "%s", from);
- res |= ast_msg_set_to(msg, "%s", to);
- if (!ast_strlen_zero(body)) {
- res |= ast_msg_set_body(msg, "%s", body);
- }
- for (current = variables; current; current = current->next) {
- res |= ast_msg_set_var_outbound(msg, current->name, current->value);
- }
- if (res) {
- ast_ari_response_alloc_failed(response);
- ast_msg_destroy(msg);
- return;
- }
- if (ast_msg_send(msg, to, from)) {
- ast_ari_response_error(response, 404, "Not Found",
- "Endpoint not found");
- }
- response->message = ast_json_null();
- response->response_code = 202;
- response->response_text = "Accepted";
- }
- /*!
- * \internal
- * \brief Convert a \c ast_json list of key/value pair tuples into a \c ast_variable list
- * \since 13.3.0
- *
- * \param[out] response HTTP response if error
- * \param json_variables The JSON blob containing the variable
- * \param[out] variables An out reference to the variables to populate.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
- static int json_to_ast_variables(struct ast_ari_response *response, struct ast_json *json_variables, struct ast_variable **variables)
- {
- enum ast_json_to_ast_vars_code res;
- res = ast_json_to_ast_variables(json_variables, variables);
- switch (res) {
- case AST_JSON_TO_AST_VARS_CODE_SUCCESS:
- return 0;
- case AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE:
- ast_ari_response_error(response, 400, "Bad Request",
- "Only string values in the 'variables' object allowed");
- break;
- case AST_JSON_TO_AST_VARS_CODE_OOM:
- ast_ari_response_alloc_failed(response);
- break;
- }
- ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to Asterisk variables\n");
- return -1;
- }
- void ast_ari_endpoints_send_message(struct ast_variable *headers,
- struct ast_ari_endpoints_send_message_args *args,
- struct ast_ari_response *response)
- {
- struct ast_variable *variables = NULL;
- if (args->variables) {
- struct ast_json *json_variables;
- ast_ari_endpoints_send_message_parse_body(args->variables, args);
- json_variables = ast_json_object_get(args->variables, "variables");
- if (json_variables
- && json_to_ast_variables(response, json_variables, &variables)) {
- return;
- }
- }
- send_message(args->to, args->from, args->body, variables, response);
- ast_variables_destroy(variables);
- }
- void ast_ari_endpoints_send_message_to_endpoint(struct ast_variable *headers,
- struct ast_ari_endpoints_send_message_to_endpoint_args *args,
- struct ast_ari_response *response)
- {
- struct ast_variable *variables = NULL;
- struct ast_endpoint_snapshot *snapshot;
- char msg_to[128];
- char *tech = ast_strdupa(args->tech);
- /* Really, we just want to know if this thing exists */
- snapshot = ast_endpoint_latest_snapshot(args->tech, args->resource);
- if (!snapshot) {
- ast_ari_response_error(response, 404, "Not Found",
- "Endpoint not found");
- return;
- }
- ao2_ref(snapshot, -1);
- if (args->variables) {
- struct ast_json *json_variables;
- ast_ari_endpoints_send_message_to_endpoint_parse_body(args->variables, args);
- json_variables = ast_json_object_get(args->variables, "variables");
- if (json_variables
- && json_to_ast_variables(response, json_variables, &variables)) {
- return;
- }
- }
- snprintf(msg_to, sizeof(msg_to), "%s:%s", ast_str_to_lower(tech), args->resource);
- send_message(msg_to, args->from, args->body, variables, response);
- ast_variables_destroy(variables);
- }
|