From 8d7873b836999b09caad87abec27579f1f065b84 Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Fri, 4 Oct 2013 16:01:48 +0000 Subject: ARI: Add subscription support This patch adds an /applications API to ARI, allowing explicit management of Stasis applications. * GET /applications - list current applications * GET /applications/{applicationName} - get details of a specific application * POST /applications/{applicationName}/subscription - explicitly subscribe to a channel, bridge or endpoint * DELETE /applications/{applicationName}/subscription - explicitly unsubscribe from a channel, bridge or endpoint Subscriptions work by a reference counting mechanism: if you subscript to an event source X number of times, you must unsubscribe X number of times to stop receiveing events for that event source. Review: https://reviewboard.asterisk.org/r/2862 (issue ASTERISK-22451) Reported by: Matt Jordan ........ Merged revisions 400522 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400523 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/ari/resource_applications.c | 173 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 res/ari/resource_applications.c (limited to 'res/ari/resource_applications.c') diff --git a/res/ari/resource_applications.c b/res/ari/resource_applications.c new file mode 100644 index 000000000..c422ad17f --- /dev/null +++ b/res/ari/resource_applications.c @@ -0,0 +1,173 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * David M. Lee, II + * + * 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/applications.{format} implementation - Stasis application + * resources + * + * \author David M. Lee, II + */ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/stasis_app.h" +#include "resource_applications.h" + +static int append_json(void *obj, void *arg, int flags) +{ + const char *app = obj; + struct ast_json *array = arg; + + ast_json_array_append(array, stasis_app_to_json(app)); + + return 0; +} + +void ast_ari_get_applications(struct ast_variable *headers, + struct ast_get_applications_args *args, + struct ast_ari_response *response) +{ + RAII_VAR(struct ao2_container *, apps, NULL, ao2_cleanup); + RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); + size_t count; + + apps = stasis_app_get_all(); + json = ast_json_array_create(); + if (!apps || !json) { + ast_ari_response_error(response, 500, "Internal Server Error", + "Allocation failed"); + return; + } + + ao2_lock(apps); + count = ao2_container_count(apps); + ao2_callback(apps, OBJ_NOLOCK | OBJ_NODATA, append_json, json); + ao2_lock(apps); + + if (count != ast_json_array_size(json)) { + ast_ari_response_error(response, 500, "Internal Server Error", + "Allocation failed"); + return; + } + + + ast_ari_response_ok(response, json); +} + +void ast_ari_get_application(struct ast_variable *headers, + struct ast_get_application_args *args, + struct ast_ari_response *response) +{ + RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); + + json = stasis_app_to_json(args->application_name); + + if (!json) { + ast_ari_response_error(response, 404, "Not Found", + "Application not found"); + return; + } + + ast_ari_response_ok(response, json); +} + +void ast_ari_application_subscribe(struct ast_variable *headers, + struct ast_application_subscribe_args *args, + struct ast_ari_response *response) +{ + RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); + enum stasis_app_subscribe_res res; + + if (args->event_source_count <= 0) { + ast_ari_response_error(response, 400, "Bad Request", + "Missing parameter eventSource"); + return; + } + + if (ast_strlen_zero(args->application_name)) { + ast_ari_response_error(response, 400, "Bad Request", + "Missing parameter applicationName"); + return; + } + + res = stasis_app_subscribe(args->application_name, args->event_source, + args->event_source_count, &json); + + switch (res) { + case STASIS_ASR_OK: + ast_ari_response_ok(response, json); + break; + case STASIS_ASR_APP_NOT_FOUND: + ast_ari_response_error(response, 404, "Not Found", + "Application not found"); + break; + case STASIS_ASR_EVENT_SOURCE_NOT_FOUND: + ast_ari_response_error(response, 422, "Unprocessable Entity", + "Event source does not exist"); + break; + case STASIS_ASR_EVENT_SOURCE_BAD_SCHEME: + ast_ari_response_error(response, 400, "Bad Request", + "Invalid event source URI scheme"); + break; + case STASIS_ASR_INTERNAL_ERROR: + ast_ari_response_error(response, 500, "Internal Server Error", + "Error processing request"); + break; + } +} + +void ast_ari_application_unsubscribe(struct ast_variable *headers, + struct ast_application_unsubscribe_args *args, + struct ast_ari_response *response) +{ + RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); + enum stasis_app_subscribe_res res; + + if (args->event_source_count == 0) { + ast_ari_response_error(response, 400, "Bad Request", + "Missing parameter eventSource"); + return; + } + + res = stasis_app_unsubscribe(args->application_name, args->event_source, + args->event_source_count, &json); + + switch (res) { + case STASIS_ASR_OK: + ast_ari_response_ok(response, json); + break; + case STASIS_ASR_APP_NOT_FOUND: + ast_ari_response_error(response, 404, "Not Found", + "Application not found"); + break; + case STASIS_ASR_EVENT_SOURCE_NOT_FOUND: + ast_ari_response_error(response, 422, "Unprocessable Entity", + "Event source was not subscribed to"); + break; + case STASIS_ASR_EVENT_SOURCE_BAD_SCHEME: + ast_ari_response_error(response, 400, "Bad Request", + "Invalid event source URI scheme"); + break; + case STASIS_ASR_INTERNAL_ERROR: + ast_ari_response_error(response, 500, "Internal Server Error", + "Error processing request"); + } +} -- cgit v1.2.3