f5a1d41abcaf68bb02f71fe78be91fe6a9641b70
[asterisk/asterisk.git] / res / res_ari_sounds.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*
20  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21  * !!!!!                               DO NOT EDIT                        !!!!!
22  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23  * This file is generated by a mustache template. Please see the original
24  * template in rest-api-templates/res_ari_resource.c.mustache
25  */
26
27 /*! \file
28  *
29  * \brief Sound resources
30  *
31  * \author David M. Lee, II <dlee@digium.com>
32  */
33
34 /*** MODULEINFO
35         <depend type="module">res_ari</depend>
36         <depend type="module">res_ari_model</depend>
37         <depend type="module">res_stasis</depend>
38         <support_level>core</support_level>
39  ***/
40
41 #include "asterisk.h"
42
43 ASTERISK_REGISTER_FILE()
44
45 #include "asterisk/app.h"
46 #include "asterisk/module.h"
47 #include "asterisk/stasis_app.h"
48 #include "ari/resource_sounds.h"
49 #if defined(AST_DEVMODE)
50 #include "ari/ari_model_validators.h"
51 #endif
52
53 #define MAX_VALS 128
54
55 int ast_ari_sounds_list_parse_body(
56         struct ast_json *body,
57         struct ast_ari_sounds_list_args *args)
58 {
59         struct ast_json *field;
60         /* Parse query parameters out of it */
61         field = ast_json_object_get(body, "lang");
62         if (field) {
63                 args->lang = ast_json_string_get(field);
64         }
65         field = ast_json_object_get(body, "format");
66         if (field) {
67                 args->format = ast_json_string_get(field);
68         }
69         return 0;
70 }
71
72 /*!
73  * \brief Parameter parsing callback for /sounds.
74  * \param get_params GET parameters in the HTTP request.
75  * \param path_vars Path variables extracted from the request.
76  * \param headers HTTP headers.
77  * \param[out] response Response to the HTTP request.
78  */
79 static void ast_ari_sounds_list_cb(
80         struct ast_tcptls_session_instance *ser,
81         struct ast_variable *get_params, struct ast_variable *path_vars,
82         struct ast_variable *headers, struct ast_ari_response *response)
83 {
84         struct ast_ari_sounds_list_args args = {};
85         struct ast_variable *i;
86         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
87 #if defined(AST_DEVMODE)
88         int is_valid;
89         int code;
90 #endif /* AST_DEVMODE */
91
92         for (i = get_params; i; i = i->next) {
93                 if (strcmp(i->name, "lang") == 0) {
94                         args.lang = (i->value);
95                 } else
96                 if (strcmp(i->name, "format") == 0) {
97                         args.format = (i->value);
98                 } else
99                 {}
100         }
101         /* Look for a JSON request entity */
102         body = ast_http_get_json(ser, headers);
103         if (!body) {
104                 switch (errno) {
105                 case EFBIG:
106                         ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
107                         goto fin;
108                 case ENOMEM:
109                         ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
110                         goto fin;
111                 case EIO:
112                         ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
113                         goto fin;
114                 }
115         }
116         if (ast_ari_sounds_list_parse_body(body, &args)) {
117                 ast_ari_response_alloc_failed(response);
118                 goto fin;
119         }
120         ast_ari_sounds_list(headers, &args, response);
121 #if defined(AST_DEVMODE)
122         code = response->response_code;
123
124         switch (code) {
125         case 0: /* Implementation is still a stub, or the code wasn't set */
126                 is_valid = response->message == NULL;
127                 break;
128         case 500: /* Internal Server Error */
129         case 501: /* Not Implemented */
130                 is_valid = 1;
131                 break;
132         default:
133                 if (200 <= code && code <= 299) {
134                         is_valid = ast_ari_validate_list(response->message,
135                                 ast_ari_validate_sound_fn());
136                 } else {
137                         ast_log(LOG_ERROR, "Invalid error response %d for /sounds\n", code);
138                         is_valid = 0;
139                 }
140         }
141
142         if (!is_valid) {
143                 ast_log(LOG_ERROR, "Response validation failed for /sounds\n");
144                 ast_ari_response_error(response, 500,
145                         "Internal Server Error", "Response validation failed");
146         }
147 #endif /* AST_DEVMODE */
148
149 fin: __attribute__((unused))
150         return;
151 }
152 /*!
153  * \brief Parameter parsing callback for /sounds/{soundId}.
154  * \param get_params GET parameters in the HTTP request.
155  * \param path_vars Path variables extracted from the request.
156  * \param headers HTTP headers.
157  * \param[out] response Response to the HTTP request.
158  */
159 static void ast_ari_sounds_get_cb(
160         struct ast_tcptls_session_instance *ser,
161         struct ast_variable *get_params, struct ast_variable *path_vars,
162         struct ast_variable *headers, struct ast_ari_response *response)
163 {
164         struct ast_ari_sounds_get_args args = {};
165         struct ast_variable *i;
166         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
167 #if defined(AST_DEVMODE)
168         int is_valid;
169         int code;
170 #endif /* AST_DEVMODE */
171
172         for (i = path_vars; i; i = i->next) {
173                 if (strcmp(i->name, "soundId") == 0) {
174                         args.sound_id = (i->value);
175                 } else
176                 {}
177         }
178         ast_ari_sounds_get(headers, &args, response);
179 #if defined(AST_DEVMODE)
180         code = response->response_code;
181
182         switch (code) {
183         case 0: /* Implementation is still a stub, or the code wasn't set */
184                 is_valid = response->message == NULL;
185                 break;
186         case 500: /* Internal Server Error */
187         case 501: /* Not Implemented */
188                 is_valid = 1;
189                 break;
190         default:
191                 if (200 <= code && code <= 299) {
192                         is_valid = ast_ari_validate_sound(
193                                 response->message);
194                 } else {
195                         ast_log(LOG_ERROR, "Invalid error response %d for /sounds/{soundId}\n", code);
196                         is_valid = 0;
197                 }
198         }
199
200         if (!is_valid) {
201                 ast_log(LOG_ERROR, "Response validation failed for /sounds/{soundId}\n");
202                 ast_ari_response_error(response, 500,
203                         "Internal Server Error", "Response validation failed");
204         }
205 #endif /* AST_DEVMODE */
206
207 fin: __attribute__((unused))
208         return;
209 }
210
211 /*! \brief REST handler for /api-docs/sounds.json */
212 static struct stasis_rest_handlers sounds_soundId = {
213         .path_segment = "soundId",
214         .is_wildcard = 1,
215         .callbacks = {
216                 [AST_HTTP_GET] = ast_ari_sounds_get_cb,
217         },
218         .num_children = 0,
219         .children = {  }
220 };
221 /*! \brief REST handler for /api-docs/sounds.json */
222 static struct stasis_rest_handlers sounds = {
223         .path_segment = "sounds",
224         .callbacks = {
225                 [AST_HTTP_GET] = ast_ari_sounds_list_cb,
226         },
227         .num_children = 1,
228         .children = { &sounds_soundId, }
229 };
230
231 static int load_module(void)
232 {
233         int res = 0;
234         stasis_app_ref();
235         res |= ast_ari_add_handler(&sounds);
236         return res;
237 }
238
239 static int unload_module(void)
240 {
241         ast_ari_remove_handler(&sounds);
242         stasis_app_unref();
243         return 0;
244 }
245
246 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Sound resources",
247         .support_level = AST_MODULE_SUPPORT_CORE,
248         .load = load_module,
249         .unload = unload_module,
250         .nonoptreq = "res_ari,res_stasis",
251 );