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