ari:Add application/json parameter support
[asterisk/asterisk.git] / res / res_ari_endpoints.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 Endpoint 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_stasis</depend>
37         <support_level>core</support_level>
38  ***/
39
40 #include "asterisk.h"
41
42 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
43
44 #include "asterisk/app.h"
45 #include "asterisk/module.h"
46 #include "asterisk/stasis_app.h"
47 #include "ari/resource_endpoints.h"
48 #if defined(AST_DEVMODE)
49 #include "ari/ari_model_validators.h"
50 #endif
51
52 #define MAX_VALS 128
53
54 /*!
55  * \brief Parameter parsing callback for /endpoints.
56  * \param get_params GET parameters in the HTTP request.
57  * \param path_vars Path variables extracted from the request.
58  * \param headers HTTP headers.
59  * \param[out] response Response to the HTTP request.
60  */
61 static void ast_ari_endpoints_list_cb(
62         struct ast_tcptls_session_instance *ser,
63         struct ast_variable *get_params, struct ast_variable *path_vars,
64         struct ast_variable *headers, struct ast_ari_response *response)
65 {
66         struct ast_ari_endpoints_list_args args = {};
67         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
68 #if defined(AST_DEVMODE)
69         int is_valid;
70         int code;
71 #endif /* AST_DEVMODE */
72
73         ast_ari_endpoints_list(headers, &args, response);
74 #if defined(AST_DEVMODE)
75         code = response->response_code;
76
77         switch (code) {
78         case 0: /* Implementation is still a stub, or the code wasn't set */
79                 is_valid = response->message == NULL;
80                 break;
81         case 500: /* Internal Server Error */
82         case 501: /* Not Implemented */
83                 is_valid = 1;
84                 break;
85         default:
86                 if (200 <= code && code <= 299) {
87                         is_valid = ast_ari_validate_list(response->message,
88                                 ast_ari_validate_endpoint_fn());
89                 } else {
90                         ast_log(LOG_ERROR, "Invalid error response %d for /endpoints\n", code);
91                         is_valid = 0;
92                 }
93         }
94
95         if (!is_valid) {
96                 ast_log(LOG_ERROR, "Response validation failed for /endpoints\n");
97                 ast_ari_response_error(response, 500,
98                         "Internal Server Error", "Response validation failed");
99         }
100 #endif /* AST_DEVMODE */
101
102 fin: __attribute__((unused))
103         return;
104 }
105 /*!
106  * \brief Parameter parsing callback for /endpoints/{tech}.
107  * \param get_params GET parameters in the HTTP request.
108  * \param path_vars Path variables extracted from the request.
109  * \param headers HTTP headers.
110  * \param[out] response Response to the HTTP request.
111  */
112 static void ast_ari_endpoints_list_by_tech_cb(
113         struct ast_tcptls_session_instance *ser,
114         struct ast_variable *get_params, struct ast_variable *path_vars,
115         struct ast_variable *headers, struct ast_ari_response *response)
116 {
117         struct ast_ari_endpoints_list_by_tech_args args = {};
118         struct ast_variable *i;
119         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
120 #if defined(AST_DEVMODE)
121         int is_valid;
122         int code;
123 #endif /* AST_DEVMODE */
124
125         for (i = path_vars; i; i = i->next) {
126                 if (strcmp(i->name, "tech") == 0) {
127                         args.tech = (i->value);
128                 } else
129                 {}
130         }
131         ast_ari_endpoints_list_by_tech(headers, &args, response);
132 #if defined(AST_DEVMODE)
133         code = response->response_code;
134
135         switch (code) {
136         case 0: /* Implementation is still a stub, or the code wasn't set */
137                 is_valid = response->message == NULL;
138                 break;
139         case 500: /* Internal Server Error */
140         case 501: /* Not Implemented */
141         case 404: /* Endpoints not found */
142                 is_valid = 1;
143                 break;
144         default:
145                 if (200 <= code && code <= 299) {
146                         is_valid = ast_ari_validate_list(response->message,
147                                 ast_ari_validate_endpoint_fn());
148                 } else {
149                         ast_log(LOG_ERROR, "Invalid error response %d for /endpoints/{tech}\n", code);
150                         is_valid = 0;
151                 }
152         }
153
154         if (!is_valid) {
155                 ast_log(LOG_ERROR, "Response validation failed for /endpoints/{tech}\n");
156                 ast_ari_response_error(response, 500,
157                         "Internal Server Error", "Response validation failed");
158         }
159 #endif /* AST_DEVMODE */
160
161 fin: __attribute__((unused))
162         return;
163 }
164 /*!
165  * \brief Parameter parsing callback for /endpoints/{tech}/{resource}.
166  * \param get_params GET parameters in the HTTP request.
167  * \param path_vars Path variables extracted from the request.
168  * \param headers HTTP headers.
169  * \param[out] response Response to the HTTP request.
170  */
171 static void ast_ari_endpoints_get_cb(
172         struct ast_tcptls_session_instance *ser,
173         struct ast_variable *get_params, struct ast_variable *path_vars,
174         struct ast_variable *headers, struct ast_ari_response *response)
175 {
176         struct ast_ari_endpoints_get_args args = {};
177         struct ast_variable *i;
178         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
179 #if defined(AST_DEVMODE)
180         int is_valid;
181         int code;
182 #endif /* AST_DEVMODE */
183
184         for (i = path_vars; i; i = i->next) {
185                 if (strcmp(i->name, "tech") == 0) {
186                         args.tech = (i->value);
187                 } else
188                 if (strcmp(i->name, "resource") == 0) {
189                         args.resource = (i->value);
190                 } else
191                 {}
192         }
193         ast_ari_endpoints_get(headers, &args, response);
194 #if defined(AST_DEVMODE)
195         code = response->response_code;
196
197         switch (code) {
198         case 0: /* Implementation is still a stub, or the code wasn't set */
199                 is_valid = response->message == NULL;
200                 break;
201         case 500: /* Internal Server Error */
202         case 501: /* Not Implemented */
203         case 404: /* Endpoints not found */
204                 is_valid = 1;
205                 break;
206         default:
207                 if (200 <= code && code <= 299) {
208                         is_valid = ast_ari_validate_endpoint(
209                                 response->message);
210                 } else {
211                         ast_log(LOG_ERROR, "Invalid error response %d for /endpoints/{tech}/{resource}\n", code);
212                         is_valid = 0;
213                 }
214         }
215
216         if (!is_valid) {
217                 ast_log(LOG_ERROR, "Response validation failed for /endpoints/{tech}/{resource}\n");
218                 ast_ari_response_error(response, 500,
219                         "Internal Server Error", "Response validation failed");
220         }
221 #endif /* AST_DEVMODE */
222
223 fin: __attribute__((unused))
224         return;
225 }
226
227 /*! \brief REST handler for /api-docs/endpoints.{format} */
228 static struct stasis_rest_handlers endpoints_tech_resource = {
229         .path_segment = "resource",
230         .is_wildcard = 1,
231         .callbacks = {
232                 [AST_HTTP_GET] = ast_ari_endpoints_get_cb,
233         },
234         .num_children = 0,
235         .children = {  }
236 };
237 /*! \brief REST handler for /api-docs/endpoints.{format} */
238 static struct stasis_rest_handlers endpoints_tech = {
239         .path_segment = "tech",
240         .is_wildcard = 1,
241         .callbacks = {
242                 [AST_HTTP_GET] = ast_ari_endpoints_list_by_tech_cb,
243         },
244         .num_children = 1,
245         .children = { &endpoints_tech_resource, }
246 };
247 /*! \brief REST handler for /api-docs/endpoints.{format} */
248 static struct stasis_rest_handlers endpoints = {
249         .path_segment = "endpoints",
250         .callbacks = {
251                 [AST_HTTP_GET] = ast_ari_endpoints_list_cb,
252         },
253         .num_children = 1,
254         .children = { &endpoints_tech, }
255 };
256
257 static int load_module(void)
258 {
259         int res = 0;
260         stasis_app_ref();
261         res |= ast_ari_add_handler(&endpoints);
262         return res;
263 }
264
265 static int unload_module(void)
266 {
267         ast_ari_remove_handler(&endpoints);
268         stasis_app_unref();
269         return 0;
270 }
271
272 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Endpoint resources",
273         .load = load_module,
274         .unload = unload_module,
275         .nonoptreq = "res_ari,res_stasis",
276         );