Asterisk - The Open Source Telephony Project GIT-master-1f1c5bb
res_ari_applications.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 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 Stasis application 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#include "asterisk/app.h"
44#include "asterisk/module.h"
45#include "asterisk/stasis_app.h"
47#if defined(AST_DEVMODE)
49#endif
50
51#define MAX_VALS 128
52
53/*!
54 * \brief Parameter parsing callback for /applications.
55 * \param ser TCP/TLS session object
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 body
60 * \param[out] response Response to the HTTP request.
61 */
64 struct ast_variable *get_params, struct ast_variable *path_vars,
65 struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
66{
68#if defined(AST_DEVMODE)
69 int is_valid;
70 int code;
71#endif /* AST_DEVMODE */
72
73 ast_ari_applications_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,
89 } else {
90 ast_log(LOG_ERROR, "Invalid error response %d for /applications\n", code);
91 is_valid = 0;
92 }
93 }
94
95 if (!is_valid) {
96 ast_log(LOG_ERROR, "Response validation failed for /applications\n");
97 ast_ari_response_error(response, 500,
98 "Internal Server Error", "Response validation failed");
99 }
100#endif /* AST_DEVMODE */
101
102fin: __attribute__((unused))
103 return;
104}
105/*!
106 * \brief Parameter parsing callback for /applications/{applicationName}.
107 * \param ser TCP/TLS session object
108 * \param get_params GET parameters in the HTTP request.
109 * \param path_vars Path variables extracted from the request.
110 * \param headers HTTP headers.
111 * \param body
112 * \param[out] response Response to the HTTP request.
113 */
115 struct ast_tcptls_session_instance *ser,
116 struct ast_variable *get_params, struct ast_variable *path_vars,
117 struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
118{
120 struct ast_variable *i;
121#if defined(AST_DEVMODE)
122 int is_valid;
123 int code;
124#endif /* AST_DEVMODE */
125
126 for (i = path_vars; i; i = i->next) {
127 if (strcmp(i->name, "applicationName") == 0) {
128 args.application_name = (i->value);
129 } else
130 {}
131 }
132 ast_ari_applications_get(headers, &args, response);
133#if defined(AST_DEVMODE)
134 code = response->response_code;
135
136 switch (code) {
137 case 0: /* Implementation is still a stub, or the code wasn't set */
138 is_valid = response->message == NULL;
139 break;
140 case 500: /* Internal Server Error */
141 case 501: /* Not Implemented */
142 case 404: /* Application does not exist. */
143 is_valid = 1;
144 break;
145 default:
146 if (200 <= code && code <= 299) {
148 response->message);
149 } else {
150 ast_log(LOG_ERROR, "Invalid error response %d for /applications/{applicationName}\n", code);
151 is_valid = 0;
152 }
153 }
154
155 if (!is_valid) {
156 ast_log(LOG_ERROR, "Response validation failed for /applications/{applicationName}\n");
157 ast_ari_response_error(response, 500,
158 "Internal Server Error", "Response validation failed");
159 }
160#endif /* AST_DEVMODE */
161
162fin: __attribute__((unused))
163 return;
164}
166 struct ast_json *body,
168{
169 struct ast_json *field;
170 /* Parse query parameters out of it */
171 field = ast_json_object_get(body, "eventSource");
172 if (field) {
173 /* If they were silly enough to both pass in a query param and a
174 * JSON body, free up the query value.
175 */
176 ast_free(args->event_source);
177 if (ast_json_typeof(field) == AST_JSON_ARRAY) {
178 /* Multiple param passed as array */
179 size_t i;
180 args->event_source_count = ast_json_array_size(field);
181 args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
182
183 if (!args->event_source) {
184 return -1;
185 }
186
187 for (i = 0; i < args->event_source_count; ++i) {
188 args->event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
189 }
190 } else {
191 /* Multiple param passed as single value */
192 args->event_source_count = 1;
193 args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
194 if (!args->event_source) {
195 return -1;
196 }
197 args->event_source[0] = ast_json_string_get(field);
198 }
199 }
200 return 0;
201}
202
203/*!
204 * \brief Parameter parsing callback for /applications/{applicationName}/subscription.
205 * \param ser TCP/TLS session object
206 * \param get_params GET parameters in the HTTP request.
207 * \param path_vars Path variables extracted from the request.
208 * \param headers HTTP headers.
209 * \param body
210 * \param[out] response Response to the HTTP request.
211 */
213 struct ast_tcptls_session_instance *ser,
214 struct ast_variable *get_params, struct ast_variable *path_vars,
215 struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
216{
218 struct ast_variable *i;
219#if defined(AST_DEVMODE)
220 int is_valid;
221 int code;
222#endif /* AST_DEVMODE */
223
224 for (i = get_params; i; i = i->next) {
225 if (strcmp(i->name, "eventSource") == 0) {
226 /* Parse comma separated list */
227 char *vals[MAX_VALS];
228 size_t j;
229
230 args.event_source_parse = ast_strdup(i->value);
231 if (!args.event_source_parse) {
233 goto fin;
234 }
235
236 if (strlen(args.event_source_parse) == 0) {
237 /* ast_app_separate_args can't handle "" */
238 args.event_source_count = 1;
239 vals[0] = args.event_source_parse;
240 } else {
241 args.event_source_count = ast_app_separate_args(
242 args.event_source_parse, ',', vals,
243 ARRAY_LEN(vals));
244 }
245
246 if (args.event_source_count == 0) {
248 goto fin;
249 }
250
251 if (args.event_source_count >= MAX_VALS) {
252 ast_ari_response_error(response, 400,
253 "Bad Request",
254 "Too many values for event_source");
255 goto fin;
256 }
257
258 args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
259 if (!args.event_source) {
261 goto fin;
262 }
263
264 for (j = 0; j < args.event_source_count; ++j) {
265 args.event_source[j] = (vals[j]);
266 }
267 } else
268 {}
269 }
270 for (i = path_vars; i; i = i->next) {
271 if (strcmp(i->name, "applicationName") == 0) {
272 args.application_name = (i->value);
273 } else
274 {}
275 }
278 goto fin;
279 }
280 ast_ari_applications_subscribe(headers, &args, response);
281#if defined(AST_DEVMODE)
282 code = response->response_code;
283
284 switch (code) {
285 case 0: /* Implementation is still a stub, or the code wasn't set */
286 is_valid = response->message == NULL;
287 break;
288 case 500: /* Internal Server Error */
289 case 501: /* Not Implemented */
290 case 400: /* Missing parameter. */
291 case 404: /* Application does not exist. */
292 case 422: /* Event source does not exist. */
293 is_valid = 1;
294 break;
295 default:
296 if (200 <= code && code <= 299) {
298 response->message);
299 } else {
300 ast_log(LOG_ERROR, "Invalid error response %d for /applications/{applicationName}/subscription\n", code);
301 is_valid = 0;
302 }
303 }
304
305 if (!is_valid) {
306 ast_log(LOG_ERROR, "Response validation failed for /applications/{applicationName}/subscription\n");
307 ast_ari_response_error(response, 500,
308 "Internal Server Error", "Response validation failed");
309 }
310#endif /* AST_DEVMODE */
311
312fin: __attribute__((unused))
313 ast_free(args.event_source_parse);
314 ast_free(args.event_source);
315 return;
316}
318 struct ast_json *body,
320{
321 struct ast_json *field;
322 /* Parse query parameters out of it */
323 field = ast_json_object_get(body, "eventSource");
324 if (field) {
325 /* If they were silly enough to both pass in a query param and a
326 * JSON body, free up the query value.
327 */
328 ast_free(args->event_source);
329 if (ast_json_typeof(field) == AST_JSON_ARRAY) {
330 /* Multiple param passed as array */
331 size_t i;
332 args->event_source_count = ast_json_array_size(field);
333 args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
334
335 if (!args->event_source) {
336 return -1;
337 }
338
339 for (i = 0; i < args->event_source_count; ++i) {
340 args->event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
341 }
342 } else {
343 /* Multiple param passed as single value */
344 args->event_source_count = 1;
345 args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count);
346 if (!args->event_source) {
347 return -1;
348 }
349 args->event_source[0] = ast_json_string_get(field);
350 }
351 }
352 return 0;
353}
354
355/*!
356 * \brief Parameter parsing callback for /applications/{applicationName}/subscription.
357 * \param ser TCP/TLS session object
358 * \param get_params GET parameters in the HTTP request.
359 * \param path_vars Path variables extracted from the request.
360 * \param headers HTTP headers.
361 * \param body
362 * \param[out] response Response to the HTTP request.
363 */
365 struct ast_tcptls_session_instance *ser,
366 struct ast_variable *get_params, struct ast_variable *path_vars,
367 struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
368{
370 struct ast_variable *i;
371#if defined(AST_DEVMODE)
372 int is_valid;
373 int code;
374#endif /* AST_DEVMODE */
375
376 for (i = get_params; i; i = i->next) {
377 if (strcmp(i->name, "eventSource") == 0) {
378 /* Parse comma separated list */
379 char *vals[MAX_VALS];
380 size_t j;
381
382 args.event_source_parse = ast_strdup(i->value);
383 if (!args.event_source_parse) {
385 goto fin;
386 }
387
388 if (strlen(args.event_source_parse) == 0) {
389 /* ast_app_separate_args can't handle "" */
390 args.event_source_count = 1;
391 vals[0] = args.event_source_parse;
392 } else {
393 args.event_source_count = ast_app_separate_args(
394 args.event_source_parse, ',', vals,
395 ARRAY_LEN(vals));
396 }
397
398 if (args.event_source_count == 0) {
400 goto fin;
401 }
402
403 if (args.event_source_count >= MAX_VALS) {
404 ast_ari_response_error(response, 400,
405 "Bad Request",
406 "Too many values for event_source");
407 goto fin;
408 }
409
410 args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
411 if (!args.event_source) {
413 goto fin;
414 }
415
416 for (j = 0; j < args.event_source_count; ++j) {
417 args.event_source[j] = (vals[j]);
418 }
419 } else
420 {}
421 }
422 for (i = path_vars; i; i = i->next) {
423 if (strcmp(i->name, "applicationName") == 0) {
424 args.application_name = (i->value);
425 } else
426 {}
427 }
430 goto fin;
431 }
432 ast_ari_applications_unsubscribe(headers, &args, response);
433#if defined(AST_DEVMODE)
434 code = response->response_code;
435
436 switch (code) {
437 case 0: /* Implementation is still a stub, or the code wasn't set */
438 is_valid = response->message == NULL;
439 break;
440 case 500: /* Internal Server Error */
441 case 501: /* Not Implemented */
442 case 400: /* Missing parameter; event source scheme not recognized. */
443 case 404: /* Application does not exist. */
444 case 409: /* Application not subscribed to event source. */
445 case 422: /* Event source does not exist. */
446 is_valid = 1;
447 break;
448 default:
449 if (200 <= code && code <= 299) {
451 response->message);
452 } else {
453 ast_log(LOG_ERROR, "Invalid error response %d for /applications/{applicationName}/subscription\n", code);
454 is_valid = 0;
455 }
456 }
457
458 if (!is_valid) {
459 ast_log(LOG_ERROR, "Response validation failed for /applications/{applicationName}/subscription\n");
460 ast_ari_response_error(response, 500,
461 "Internal Server Error", "Response validation failed");
462 }
463#endif /* AST_DEVMODE */
464
465fin: __attribute__((unused))
466 ast_free(args.event_source_parse);
467 ast_free(args.event_source);
468 return;
469}
471 struct ast_json *body,
473{
474 /* Parse query parameters out of it */
475 return 0;
476}
477
478/*!
479 * \brief Parameter parsing callback for /applications/{applicationName}/eventFilter.
480 * \param ser TCP/TLS session object
481 * \param get_params GET parameters in the HTTP request.
482 * \param path_vars Path variables extracted from the request.
483 * \param headers HTTP headers.
484 * \param body
485 * \param[out] response Response to the HTTP request.
486 */
488 struct ast_tcptls_session_instance *ser,
489 struct ast_variable *get_params, struct ast_variable *path_vars,
490 struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
491{
493 struct ast_variable *i;
494#if defined(AST_DEVMODE)
495 int is_valid;
496 int code;
497#endif /* AST_DEVMODE */
498
499 for (i = path_vars; i; i = i->next) {
500 if (strcmp(i->name, "applicationName") == 0) {
501 args.application_name = (i->value);
502 } else
503 {}
504 }
505 args.filter = body;
506 ast_ari_applications_filter(headers, &args, response);
507#if defined(AST_DEVMODE)
508 code = response->response_code;
509
510 switch (code) {
511 case 0: /* Implementation is still a stub, or the code wasn't set */
512 is_valid = response->message == NULL;
513 break;
514 case 500: /* Internal Server Error */
515 case 501: /* Not Implemented */
516 case 400: /* Bad request. */
517 case 404: /* Application does not exist. */
518 is_valid = 1;
519 break;
520 default:
521 if (200 <= code && code <= 299) {
523 response->message);
524 } else {
525 ast_log(LOG_ERROR, "Invalid error response %d for /applications/{applicationName}/eventFilter\n", code);
526 is_valid = 0;
527 }
528 }
529
530 if (!is_valid) {
531 ast_log(LOG_ERROR, "Response validation failed for /applications/{applicationName}/eventFilter\n");
532 ast_ari_response_error(response, 500,
533 "Internal Server Error", "Response validation failed");
534 }
535#endif /* AST_DEVMODE */
536
537fin: __attribute__((unused))
538 return;
539}
540
541/*! \brief REST handler for /api-docs/applications.json */
543 .path_segment = "subscription",
544 .callbacks = {
547 },
548 .num_children = 0,
549 .children = { }
550};
551/*! \brief REST handler for /api-docs/applications.json */
553 .path_segment = "eventFilter",
554 .callbacks = {
556 },
557 .num_children = 0,
558 .children = { }
559};
560/*! \brief REST handler for /api-docs/applications.json */
562 .path_segment = "applicationName",
563 .is_wildcard = 1,
564 .callbacks = {
566 },
567 .num_children = 2,
569};
570/*! \brief REST handler for /api-docs/applications.json */
572 .path_segment = "applications",
573 .callbacks = {
575 },
576 .num_children = 1,
577 .children = { &applications_applicationName, }
578};
579
580static int unload_module(void)
581{
583 return 0;
584}
585
586static int load_module(void)
587{
588 int res = 0;
589
590
592 if (res) {
595 }
596
598}
599
600AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Stasis application resources",
601 .support_level = AST_MODULE_SUPPORT_CORE,
602 .load = load_module,
603 .unload = unload_module,
604 .requires = "res_ari,res_ari_model,res_stasis",
int ast_ari_remove_handler(struct stasis_rest_handlers *handler)
Definition: res_ari.c:202
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
int ast_ari_add_handler(struct stasis_rest_handlers *handler)
Definition: res_ari.c:179
ari_validator ast_ari_validate_application_fn(void)
Function pointer to ast_ari_validate_application().
int ast_ari_validate_application(struct ast_json *json)
Validator for Application.
Generated file - Build validators for ARI model objects.
int ast_ari_validate_list(struct ast_json *json, int(*fn)(struct ast_json *))
Validator for a Swagger List[]/JSON array.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_log
Definition: astobj2.c:42
@ AST_HTTP_PUT
Definition: http.h:63
@ AST_HTTP_DELETE
Definition: http.h:64
@ AST_HTTP_POST
Definition: http.h:61
@ AST_HTTP_GET
Definition: http.h:60
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define ast_app_separate_args(a, b, c, d)
#define LOG_ERROR
enum ast_json_type ast_json_typeof(const struct ast_json *value)
Get the type of value.
Definition: json.c:78
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition: json.c:370
@ AST_JSON_ARRAY
Definition: json.h:165
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition: json.c:366
Asterisk module definitions.
@ AST_MODFLAG_DEFAULT
Definition: module.h:329
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:557
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int ast_ari_applications_filter_parse_body(struct ast_json *body, struct ast_ari_applications_filter_args *args)
Body parsing function for /applications/{applicationName}/eventFilter.
static void ast_ari_applications_unsubscribe_cb(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Parameter parsing callback for /applications/{applicationName}/subscription.
int ast_ari_applications_subscribe_parse_body(struct ast_json *body, struct ast_ari_applications_subscribe_args *args)
Body parsing function for /applications/{applicationName}/subscription.
#define MAX_VALS
static void ast_ari_applications_list_cb(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Parameter parsing callback for /applications.
static struct stasis_rest_handlers applications
REST handler for /api-docs/applications.json.
static struct stasis_rest_handlers applications_applicationName
REST handler for /api-docs/applications.json.
static void ast_ari_applications_get_cb(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Parameter parsing callback for /applications/{applicationName}.
static struct stasis_rest_handlers applications_applicationName_eventFilter
REST handler for /api-docs/applications.json.
int ast_ari_applications_unsubscribe_parse_body(struct ast_json *body, struct ast_ari_applications_unsubscribe_args *args)
Body parsing function for /applications/{applicationName}/subscription.
static int load_module(void)
static int unload_module(void)
static void ast_ari_applications_subscribe_cb(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Parameter parsing callback for /applications/{applicationName}/subscription.
static struct stasis_rest_handlers applications_applicationName_subscription
REST handler for /api-docs/applications.json.
static void ast_ari_applications_filter_cb(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Parameter parsing callback for /applications/{applicationName}/eventFilter.
#define NULL
Definition: resample.c:96
void ast_ari_applications_subscribe(struct ast_variable *headers, struct ast_ari_applications_subscribe_args *args, struct ast_ari_response *response)
Subscribe an application to a event source.
void ast_ari_applications_get(struct ast_variable *headers, struct ast_ari_applications_get_args *args, struct ast_ari_response *response)
Get details of an application.
void ast_ari_applications_list(struct ast_variable *headers, struct ast_ari_applications_list_args *args, struct ast_ari_response *response)
List all applications.
void ast_ari_applications_filter(struct ast_variable *headers, struct ast_ari_applications_filter_args *args, struct ast_ari_response *response)
Filter application events types.
void ast_ari_applications_unsubscribe(struct ast_variable *headers, struct ast_ari_applications_unsubscribe_args *args, struct ast_ari_response *response)
Unsubscribe an application from an event source.
Generated file - declares stubs to be implemented in res/ari/resource_applications....
Stasis Application API. See Stasis Application API for detailed documentation.
struct ast_json * message
Definition: ari.h:94
int response_code
Definition: ari.h:99
Abstract JSON element (object, array, string, int, ...).
describes a server instance
Definition: tcptls.h:150
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Handler for a single RESTful path segment.
Definition: ari.h:69
const char * path_segment
Definition: ari.h:71
const char * args
#define ARRAY_LEN(a)
Definition: utils.h:666