[asterisk-commits] dlee: branch dlee/ASTERISK-22451-ari-subscribe r398693 - in /team/dlee/ASTERI...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Sep 9 16:48:33 CDT 2013
Author: dlee
Date: Mon Sep 9 16:48:31 2013
New Revision: 398693
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=398693
Log:
API
Modified:
team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.c
team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.h
team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.c
team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.h
team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.c
team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.h
team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_channels.c
team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_endpoints.c
team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/channels.json
team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/endpoints.json
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.c?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.c (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.c Mon Sep 9 16:48:31 2013
@@ -588,6 +588,45 @@
return ast_ari_validate_endpoint;
}
+int ast_ari_validate_endpoint_subscriptions(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_applications = 0;
+
+ for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("applications", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_applications = 1;
+ prop_is_valid = ast_ari_validate_list(
+ ast_json_object_iter_value(iter),
+ ast_ari_validate_string);
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI EndpointSubscriptions field applications failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI EndpointSubscriptions has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_applications) {
+ ast_log(LOG_ERROR, "ARI EndpointSubscriptions missing required field applications\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_endpoint_subscriptions_fn(void)
+{
+ return ast_ari_validate_endpoint_subscriptions;
+}
+
int ast_ari_validate_caller_id(struct ast_json *json)
{
int res = 1;
@@ -792,6 +831,45 @@
return ast_ari_validate_channel;
}
+int ast_ari_validate_channel_subscriptions(struct ast_json *json)
+{
+ int res = 1;
+ struct ast_json_iter *iter;
+ int has_applications = 0;
+
+ for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("applications", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ has_applications = 1;
+ prop_is_valid = ast_ari_validate_list(
+ ast_json_object_iter_value(iter),
+ ast_ari_validate_string);
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelSubscriptions field applications failed validation\n");
+ res = 0;
+ }
+ } else
+ {
+ ast_log(LOG_ERROR,
+ "ARI ChannelSubscriptions has undocumented field %s\n",
+ ast_json_object_iter_key(iter));
+ res = 0;
+ }
+ }
+
+ if (!has_applications) {
+ ast_log(LOG_ERROR, "ARI ChannelSubscriptions missing required field applications\n");
+ res = 0;
+ }
+
+ return res;
+}
+
+ari_validator ast_ari_validate_channel_subscriptions_fn(void)
+{
+ return ast_ari_validate_channel_subscriptions;
+}
+
int ast_ari_validate_dialed(struct ast_json *json)
{
int res = 1;
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.h?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.h (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/ari/ari_model_validators.h Mon Sep 9 16:48:31 2013
@@ -290,6 +290,24 @@
ari_validator ast_ari_validate_endpoint_fn(void);
/*!
+ * \brief Validator for EndpointSubscriptions.
+ *
+ * List of applications subscribed to a endpoint
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_endpoint_subscriptions(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_endpoint_subscriptions().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_endpoint_subscriptions_fn(void);
+
+/*!
* \brief Validator for CallerID.
*
* Caller identification
@@ -324,6 +342,24 @@
* See \ref ast_ari_model_validators.h for more details.
*/
ari_validator ast_ari_validate_channel_fn(void);
+
+/*!
+ * \brief Validator for ChannelSubscriptions.
+ *
+ * List of applications subscribed to a channel
+ *
+ * \param json JSON object to validate.
+ * \returns True (non-zero) if valid.
+ * \returns False (zero) if invalid.
+ */
+int ast_ari_validate_channel_subscriptions(struct ast_json *json);
+
+/*!
+ * \brief Function pointer to ast_ari_validate_channel_subscriptions().
+ *
+ * See \ref ast_ari_model_validators.h for more details.
+ */
+ari_validator ast_ari_validate_channel_subscriptions_fn(void);
/*!
* \brief Validator for Dialed.
@@ -909,6 +945,8 @@
* - resource: string (required)
* - state: string
* - technology: string (required)
+ * EndpointSubscriptions
+ * - applications: List[string] (required)
* CallerID
* - name: string (required)
* - number: string (required)
@@ -921,6 +959,8 @@
* - id: string (required)
* - name: string (required)
* - state: string (required)
+ * ChannelSubscriptions
+ * - applications: List[string] (required)
* Dialed
* DialplanCEP
* - context: string (required)
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.c?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.c (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.c Mon Sep 9 16:48:31 2013
@@ -700,3 +700,20 @@
ast_ari_response_no_content(response);
}
+void ast_ari_get_channel_subscriptions(struct ast_variable *headers,
+ struct ast_get_channel_subscriptions_args *args,
+ struct ast_ari_response *response)
+{
+}
+
+void ast_ari_channel_subscribe(struct ast_variable *headers,
+ struct ast_channel_subscribe_args *args,
+ struct ast_ari_response *response)
+{
+}
+
+void ast_ari_channel_unsubscribe(struct ast_variable *headers,
+ struct ast_channel_unsubscribe_args *args,
+ struct ast_ari_response *response)
+{
+}
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.h?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.h (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_channels.h Mon Sep 9 16:48:31 2013
@@ -328,5 +328,56 @@
* \param[out] response HTTP response
*/
void ast_ari_set_channel_var(struct ast_variable *headers, struct ast_set_channel_var_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_get_channel_subscriptions() */
+struct ast_get_channel_subscriptions_args {
+ /*! \brief Channel's id */
+ const char *channel_id;
+};
+/*!
+ * \brief Returns the current subscriptions for a channel.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_get_channel_subscriptions(struct ast_variable *headers, struct ast_get_channel_subscriptions_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_channel_subscribe() */
+struct ast_channel_subscribe_args {
+ /*! \brief Channel's id */
+ const char *channel_id;
+ /*! \brief Array of Application(s) which to subscribe to a channel */
+ const char **application;
+ /*! \brief Length of application array. */
+ size_t application_count;
+ /*! \brief Parsing context for application. */
+ char *application_parse;
+};
+/*!
+ * \brief Create a new subscription for a channel.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_channel_subscribe(struct ast_variable *headers, struct ast_channel_subscribe_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_channel_unsubscribe() */
+struct ast_channel_unsubscribe_args {
+ /*! \brief Channel's id */
+ const char *channel_id;
+ /*! \brief Array of Application(s) which to subscribe to a channel */
+ const char **application;
+ /*! \brief Length of application array. */
+ size_t application_count;
+ /*! \brief Parsing context for application. */
+ char *application_parse;
+};
+/*!
+ * \brief Remove a subscription for a channel.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_channel_unsubscribe(struct ast_variable *headers, struct ast_channel_unsubscribe_args *args, struct ast_ari_response *response);
#endif /* _ASTERISK_RESOURCE_CHANNELS_H */
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.c?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.c (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.c Mon Sep 9 16:48:31 2013
@@ -155,3 +155,21 @@
ast_ari_response_ok(response, ast_json_ref(json));
}
+
+void ast_ari_get_endpoint_subscriptions(struct ast_variable *headers,
+ struct ast_get_endpoint_subscriptions_args *args,
+ struct ast_ari_response *response)
+{
+}
+
+void ast_ari_endpoint_subscribe(struct ast_variable *headers,
+ struct ast_endpoint_subscribe_args *args,
+ struct ast_ari_response *response)
+{
+}
+
+void ast_ari_endpoint_unsubscribe(struct ast_variable *headers,
+ struct ast_endpoint_unsubscribe_args *args,
+ struct ast_ari_response *response)
+{
+}
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.h?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.h (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/ari/resource_endpoints.h Mon Sep 9 16:48:31 2013
@@ -78,5 +78,62 @@
* \param[out] response HTTP response
*/
void ast_ari_get_endpoint(struct ast_variable *headers, struct ast_get_endpoint_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_get_endpoint_subscriptions() */
+struct ast_get_endpoint_subscriptions_args {
+ /*! \brief Technology of the endpoint */
+ const char *tech;
+ /*! \brief ID of the endpoint */
+ const char *resource;
+};
+/*!
+ * \brief Returns the current subscriptions for a endpoint.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_get_endpoint_subscriptions(struct ast_variable *headers, struct ast_get_endpoint_subscriptions_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_endpoint_subscribe() */
+struct ast_endpoint_subscribe_args {
+ /*! \brief Technology of the endpoint */
+ const char *tech;
+ /*! \brief ID of the endpoint */
+ const char *resource;
+ /*! \brief Array of Application(s) which to subscribe to a endpoint */
+ const char **application;
+ /*! \brief Length of application array. */
+ size_t application_count;
+ /*! \brief Parsing context for application. */
+ char *application_parse;
+};
+/*!
+ * \brief Create a new subscription for a endpoint.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_endpoint_subscribe(struct ast_variable *headers, struct ast_endpoint_subscribe_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_endpoint_unsubscribe() */
+struct ast_endpoint_unsubscribe_args {
+ /*! \brief Technology of the endpoint */
+ const char *tech;
+ /*! \brief ID of the endpoint */
+ const char *resource;
+ /*! \brief Array of Application(s) which to subscribe to a endpoint */
+ const char **application;
+ /*! \brief Length of application array. */
+ size_t application_count;
+ /*! \brief Parsing context for application. */
+ char *application_parse;
+};
+/*!
+ * \brief Remove a subscription for a endpoint.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_endpoint_unsubscribe(struct ast_variable *headers, struct ast_endpoint_unsubscribe_args *args, struct ast_ari_response *response);
#endif /* _ASTERISK_RESOURCE_ENDPOINTS_H */
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_channels.c?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_channels.c (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_channels.c Mon Sep 9 16:48:31 2013
@@ -1146,6 +1146,276 @@
#endif /* AST_DEVMODE */
fin: __attribute__((unused))
+ return;
+}
+/*!
+ * \brief Parameter parsing callback for /channels/{channelId}/subscriptions.
+ * \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_get_channel_subscriptions_cb(
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_get_channel_subscriptions_args args = {};
+ struct ast_variable *i;
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ {}
+ }
+ ast_ari_get_channel_subscriptions(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_channel_subscriptions(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/subscriptions\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/subscriptions\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 /channels/{channelId}/subscriptions.
+ * \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_channel_subscribe_cb(
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_channel_subscribe_args args = {};
+ struct ast_variable *i;
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "application") == 0) {
+ /* Parse comma separated list */
+ char *vals[MAX_VALS];
+ size_t j;
+
+ args.application_parse = ast_strdup(i->value);
+ if (!args.application_parse) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (strlen(args.application_parse) == 0) {
+ /* ast_app_separate_args can't handle "" */
+ args.application_count = 1;
+ vals[0] = args.application_parse;
+ } else {
+ args.application_count = ast_app_separate_args(
+ args.application_parse, ',', vals,
+ ARRAY_LEN(vals));
+ }
+
+ if (args.application_count == 0) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (args.application_count >= MAX_VALS) {
+ ast_ari_response_error(response, 400,
+ "Bad Request",
+ "Too many values for application");
+ goto fin;
+ }
+
+ args.application = ast_malloc(sizeof(*args.application) * args.application_count);
+ if (!args.application) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (j = 0; j < args.application_count; ++j) {
+ args.application[j] = (vals[j]);
+ }
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ {}
+ }
+ ast_ari_channel_subscribe(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: /* Channel not found. */
+ case 409: /* Application alreadt subscribed to this channel */
+ case 422: /* Application not found. */
+ 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 /channels/{channelId}/subscriptions\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/subscriptions\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+ ast_free(args.application_parse);
+ ast_free(args.application);
+ return;
+}
+/*!
+ * \brief Parameter parsing callback for /channels/{channelId}/subscriptions.
+ * \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_channel_unsubscribe_cb(
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_channel_unsubscribe_args args = {};
+ struct ast_variable *i;
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "application") == 0) {
+ /* Parse comma separated list */
+ char *vals[MAX_VALS];
+ size_t j;
+
+ args.application_parse = ast_strdup(i->value);
+ if (!args.application_parse) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (strlen(args.application_parse) == 0) {
+ /* ast_app_separate_args can't handle "" */
+ args.application_count = 1;
+ vals[0] = args.application_parse;
+ } else {
+ args.application_count = ast_app_separate_args(
+ args.application_parse, ',', vals,
+ ARRAY_LEN(vals));
+ }
+
+ if (args.application_count == 0) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (args.application_count >= MAX_VALS) {
+ ast_ari_response_error(response, 400,
+ "Bad Request",
+ "Too many values for application");
+ goto fin;
+ }
+
+ args.application = ast_malloc(sizeof(*args.application) * args.application_count);
+ if (!args.application) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (j = 0; j < args.application_count; ++j) {
+ args.application[j] = (vals[j]);
+ }
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ {}
+ }
+ ast_ari_channel_unsubscribe(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: /* Channel not found. */
+ case 409: /* Application not subscribed to this channel */
+ case 422: /* Application not found. */
+ 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 /channels/{channelId}/subscriptions\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/subscriptions\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+ ast_free(args.application_parse);
+ ast_free(args.application);
return;
}
@@ -1259,6 +1529,17 @@
.children = { }
};
/*! \brief REST handler for /api-docs/channels.{format} */
+static struct stasis_rest_handlers channels_channelId_subscriptions = {
+ .path_segment = "subscriptions",
+ .callbacks = {
+ [AST_HTTP_GET] = ast_ari_get_channel_subscriptions_cb,
+ [AST_HTTP_POST] = ast_ari_channel_subscribe_cb,
+ [AST_HTTP_DELETE] = ast_ari_channel_unsubscribe_cb,
+ },
+ .num_children = 0,
+ .children = { }
+};
+/*! \brief REST handler for /api-docs/channels.{format} */
static struct stasis_rest_handlers channels_channelId = {
.path_segment = "channelId",
.is_wildcard = 1,
@@ -1266,8 +1547,8 @@
[AST_HTTP_GET] = ast_ari_get_channel_cb,
[AST_HTTP_DELETE] = ast_ari_delete_channel_cb,
},
- .num_children = 12,
- .children = { &channels_channelId_dial,&channels_channelId_continue,&channels_channelId_answer,&channels_channelId_mute,&channels_channelId_unmute,&channels_channelId_hold,&channels_channelId_unhold,&channels_channelId_mohstart,&channels_channelId_mohstop,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable, }
+ .num_children = 13,
+ .children = { &channels_channelId_dial,&channels_channelId_continue,&channels_channelId_answer,&channels_channelId_mute,&channels_channelId_unmute,&channels_channelId_hold,&channels_channelId_unhold,&channels_channelId_mohstart,&channels_channelId_mohstop,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable,&channels_channelId_subscriptions, }
};
/*! \brief REST handler for /api-docs/channels.{format} */
static struct stasis_rest_handlers channels = {
Modified: team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_endpoints.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_endpoints.c?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_endpoints.c (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/res/res_ari_endpoints.c Mon Sep 9 16:48:31 2013
@@ -215,7 +215,297 @@
fin: __attribute__((unused))
return;
}
-
+/*!
+ * \brief Parameter parsing callback for /endpoints/{tech}/{resource}/subscriptions.
+ * \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_get_endpoint_subscriptions_cb(
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_get_endpoint_subscriptions_args args = {};
+ struct ast_variable *i;
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "tech") == 0) {
+ args.tech = (i->value);
+ } else
+ if (strcmp(i->name, "resource") == 0) {
+ args.resource = (i->value);
+ } else
+ {}
+ }
+ ast_ari_get_endpoint_subscriptions(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_endpoint_subscriptions(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /endpoints/{tech}/{resource}/subscriptions\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /endpoints/{tech}/{resource}/subscriptions\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 /endpoints/{tech}/{resource}/subscriptions.
+ * \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_endpoint_subscribe_cb(
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_endpoint_subscribe_args args = {};
+ struct ast_variable *i;
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "application") == 0) {
+ /* Parse comma separated list */
+ char *vals[MAX_VALS];
+ size_t j;
+
+ args.application_parse = ast_strdup(i->value);
+ if (!args.application_parse) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (strlen(args.application_parse) == 0) {
+ /* ast_app_separate_args can't handle "" */
+ args.application_count = 1;
+ vals[0] = args.application_parse;
+ } else {
+ args.application_count = ast_app_separate_args(
+ args.application_parse, ',', vals,
+ ARRAY_LEN(vals));
+ }
+
+ if (args.application_count == 0) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (args.application_count >= MAX_VALS) {
+ ast_ari_response_error(response, 400,
+ "Bad Request",
+ "Too many values for application");
+ goto fin;
+ }
+
+ args.application = ast_malloc(sizeof(*args.application) * args.application_count);
+ if (!args.application) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (j = 0; j < args.application_count; ++j) {
+ args.application[j] = (vals[j]);
+ }
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "tech") == 0) {
+ args.tech = (i->value);
+ } else
+ if (strcmp(i->name, "resource") == 0) {
+ args.resource = (i->value);
+ } else
+ {}
+ }
+ ast_ari_endpoint_subscribe(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: /* Endpoint not found. */
+ case 409: /* Application alreadt subscribed to this endpoint */
+ case 422: /* Application not found. */
+ 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 /endpoints/{tech}/{resource}/subscriptions\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /endpoints/{tech}/{resource}/subscriptions\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+ ast_free(args.application_parse);
+ ast_free(args.application);
+ return;
+}
+/*!
+ * \brief Parameter parsing callback for /endpoints/{tech}/{resource}/subscriptions.
+ * \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_endpoint_unsubscribe_cb(
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_endpoint_unsubscribe_args args = {};
+ struct ast_variable *i;
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "application") == 0) {
+ /* Parse comma separated list */
+ char *vals[MAX_VALS];
+ size_t j;
+
+ args.application_parse = ast_strdup(i->value);
+ if (!args.application_parse) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (strlen(args.application_parse) == 0) {
+ /* ast_app_separate_args can't handle "" */
+ args.application_count = 1;
+ vals[0] = args.application_parse;
+ } else {
+ args.application_count = ast_app_separate_args(
+ args.application_parse, ',', vals,
+ ARRAY_LEN(vals));
+ }
+
+ if (args.application_count == 0) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ if (args.application_count >= MAX_VALS) {
+ ast_ari_response_error(response, 400,
+ "Bad Request",
+ "Too many values for application");
+ goto fin;
+ }
+
+ args.application = ast_malloc(sizeof(*args.application) * args.application_count);
+ if (!args.application) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (j = 0; j < args.application_count; ++j) {
+ args.application[j] = (vals[j]);
+ }
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "tech") == 0) {
+ args.tech = (i->value);
+ } else
+ if (strcmp(i->name, "resource") == 0) {
+ args.resource = (i->value);
+ } else
+ {}
+ }
+ ast_ari_endpoint_unsubscribe(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: /* Endpoint not found. */
+ case 409: /* Application not subscribed to this endpoint */
+ case 422: /* Application not found. */
+ 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 /endpoints/{tech}/{resource}/subscriptions\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /endpoints/{tech}/{resource}/subscriptions\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
+fin: __attribute__((unused))
+ ast_free(args.application_parse);
+ ast_free(args.application);
+ return;
+}
+
+/*! \brief REST handler for /api-docs/endpoints.{format} */
+static struct stasis_rest_handlers endpoints_tech_resource_subscriptions = {
+ .path_segment = "subscriptions",
+ .callbacks = {
+ [AST_HTTP_GET] = ast_ari_get_endpoint_subscriptions_cb,
+ [AST_HTTP_POST] = ast_ari_endpoint_subscribe_cb,
+ [AST_HTTP_DELETE] = ast_ari_endpoint_unsubscribe_cb,
+ },
+ .num_children = 0,
+ .children = { }
+};
/*! \brief REST handler for /api-docs/endpoints.{format} */
static struct stasis_rest_handlers endpoints_tech_resource = {
.path_segment = "resource",
@@ -223,8 +513,8 @@
.callbacks = {
[AST_HTTP_GET] = ast_ari_get_endpoint_cb,
},
- .num_children = 0,
- .children = { }
+ .num_children = 1,
+ .children = { &endpoints_tech_resource_subscriptions, }
};
/*! \brief REST handler for /api-docs/endpoints.{format} */
static struct stasis_rest_handlers endpoints_tech = {
Modified: team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/channels.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/channels.json?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/channels.json (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/channels.json Mon Sep 9 16:48:31 2013
@@ -811,6 +811,104 @@
{
"code": 409,
"reason": "Channel not in a Stasis application"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "path": "/channels/{channelId}/subscriptions",
+ "description": "Manually manage Stasis application subscriptions for a channel",
+ "operations": [
+ {
+ "httpMethod": "GET",
+ "summary": "Returns the current subscriptions for a channel.",
+ "nickname": "getChannelSubscriptions",
+ "responseClass": "ChannelSubscriptions",
+ "parameters": [
+ {
+ "name": "channelId",
+ "description": "Channel's id",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ }
+ ]
+ },
+ {
+ "httpMethod": "POST",
+ "summary": "Create a new subscription for a channel.",
+ "nickname": "channelSubscribe",
+ "responseClass": "void",
+ "parameters": [
+ {
+ "name": "channelId",
+ "description": "Channel's id",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "application",
+ "description": "Application(s) which to subscribe to a channel",
+ "paramType": "query",
+ "required": true,
+ "allowMultiple": true,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 404,
+ "reason": "Channel not found."
+ },
+ {
+ "code": 409,
+ "reason": "Application alreadt subscribed to this channel"
+ },
+ {
+ "code": 422,
+ "reason": "Application not found."
+ }
+ ]
+ },
+ {
+ "httpMethod": "DELETE",
+ "summary": "Remove a subscription for a channel.",
+ "nickname": "channelUnsubscribe",
+ "responseClass": "void",
+ "parameters": [
+ {
+ "name": "channelId",
+ "description": "Channel's id",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "application",
+ "description": "Application(s) which to subscribe to a channel",
+ "paramType": "query",
+ "required": true,
+ "allowMultiple": true,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 404,
+ "reason": "Channel not found."
+ },
+ {
+ "code": 409,
+ "reason": "Application not subscribed to this channel"
+ },
+ {
+ "code": 422,
+ "reason": "Application not found."
}
]
}
@@ -915,6 +1013,17 @@
"description": "Timestamp when channel was created"
}
}
+ },
+ "ChannelSubscriptions": {
+ "id": "ChannelSubscriptions",
+ "description": "List of applications subscribed to a channel",
+ "properties": {
+ "applications": {
+ "required": true,
+ "type": "List[string]",
+ "description": "List of applications subscribed to this channel"
+ }
+ }
}
}
}
Modified: team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/endpoints.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/endpoints.json?view=diff&rev=398693&r1=398692&r2=398693
==============================================================================
--- team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/endpoints.json (original)
+++ team/dlee/ASTERISK-22451-ari-subscribe/rest-api/api-docs/endpoints.json Mon Sep 9 16:48:31 2013
@@ -60,6 +60,116 @@
"description": "ID of the endpoint",
"paramType": "path",
"dataType": "string"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "path": "/endpoints/{tech}/{resource}/subscriptions",
+ "description": "Manually manage Stasis application subscriptions for an endpoint",
+ "operations": [
+ {
+ "httpMethod": "GET",
+ "summary": "Returns the current subscriptions for a endpoint.",
+ "nickname": "getEndpointSubscriptions",
+ "responseClass": "EndpointSubscriptions",
+ "parameters": [
+ {
+ "name": "tech",
+ "description": "Technology of the endpoint",
+ "paramType": "path",
+ "dataType": "string"
+ },
+ {
+ "name": "resource",
+ "description": "ID of the endpoint",
+ "paramType": "path",
+ "dataType": "string"
+ }
+ ]
+ },
+ {
+ "httpMethod": "POST",
+ "summary": "Create a new subscription for a endpoint.",
+ "nickname": "endpointSubscribe",
+ "responseClass": "void",
+ "parameters": [
+ {
+ "name": "tech",
+ "description": "Technology of the endpoint",
+ "paramType": "path",
+ "dataType": "string"
+ },
+ {
+ "name": "resource",
+ "description": "ID of the endpoint",
+ "paramType": "path",
+ "dataType": "string"
+ },
+ {
+ "name": "application",
+ "description": "Application(s) which to subscribe to a endpoint",
+ "paramType": "query",
+ "required": true,
+ "allowMultiple": true,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 404,
+ "reason": "Endpoint not found."
+ },
+ {
+ "code": 409,
+ "reason": "Application alreadt subscribed to this endpoint"
+ },
+ {
+ "code": 422,
+ "reason": "Application not found."
+ }
+ ]
+ },
+ {
+ "httpMethod": "DELETE",
+ "summary": "Remove a subscription for a endpoint.",
+ "nickname": "endpointUnsubscribe",
+ "responseClass": "void",
+ "parameters": [
+ {
+ "name": "tech",
+ "description": "Technology of the endpoint",
+ "paramType": "path",
+ "dataType": "string"
+ },
+ {
+ "name": "resource",
+ "description": "ID of the endpoint",
+ "paramType": "path",
+ "dataType": "string"
+ },
+ {
+ "name": "application",
[... 41 lines stripped ...]
More information about the asterisk-commits
mailing list