Address unload order issues for res_stasis* modules
[asterisk/asterisk.git] / rest-api-templates / res_stasis_http_resource.c.mustache
1 {{#api_declaration}}
2 /*
3  * Asterisk -- An open source telephony toolkit.
4  *
5  * {{{copyright}}}
6  *
7  * {{{author}}}
8 {{! Template Copyright
9  * Copyright (C) 2013, Digium, Inc.
10  *
11  * David M. Lee, II <dlee@digium.com>
12 }}
13  *
14  * See http://www.asterisk.org for more information about
15  * the Asterisk project. Please do not directly contact
16  * any of the maintainers of this project for assistance;
17  * the project provides a web site, mailing lists and IRC
18  * channels for your use.
19  *
20  * This program is free software, distributed under the terms of
21  * the GNU General Public License Version 2. See the LICENSE file
22  * at the top of the source tree.
23  */
24
25 {{! Template for rendering the res_ module for an HTTP resource. }}
26 /*
27 {{> do-not-edit}}
28  * This file is generated by a mustache template. Please see the original
29  * template in rest-api-templates/res_stasis_http_resource.c.mustache
30  */
31
32 /*! \file
33  *
34  * \brief {{{description}}}
35  *
36  * \author {{{author}}}
37  */
38
39 /*** MODULEINFO
40         <depend type="module">res_stasis_http</depend>
41         <depend type="module">res_stasis</depend>
42         <support_level>core</support_level>
43  ***/
44
45 #include "asterisk.h"
46
47 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
48
49 #include "asterisk/module.h"
50 #include "asterisk/stasis_app.h"
51 #include "stasis_http/resource_{{name}}.h"
52 {{#has_events}}
53 #include "asterisk/stasis_channels.h"
54 {{/has_events}}
55
56 {{#apis}}
57 {{#operations}}
58 /*!
59  * \brief Parameter parsing callback for {{path}}.
60  * \param get_params GET parameters in the HTTP request.
61  * \param path_vars Path variables extracted from the request.
62  * \param headers HTTP headers.
63  * \param[out] response Response to the HTTP request.
64  */
65 static void stasis_http_{{c_nickname}}_cb(
66     struct ast_variable *get_params, struct ast_variable *path_vars,
67     struct ast_variable *headers, struct stasis_http_response *response)
68 {
69         struct ast_{{c_nickname}}_args args = {};
70 {{#has_parameters}}
71         struct ast_variable *i;
72
73 {{#has_query_parameters}}
74         for (i = get_params; i; i = i->next) {
75 {{#query_parameters}}
76                 if (strcmp(i->name, "{{name}}") == 0) {
77                         args.{{c_name}} = {{c_convert}}(i->value);
78                 } else
79 {{/query_parameters}}
80                 {}
81         }
82 {{/has_query_parameters}}
83 {{#has_path_parameters}}
84         for (i = path_vars; i; i = i->next) {
85 {{#path_parameters}}
86                 if (strcmp(i->name, "{{name}}") == 0) {
87                         args.{{c_name}} = {{c_convert}}(i->value);
88                 } else
89 {{/path_parameters}}
90                 {}
91         }
92 {{/has_path_parameters}}
93 {{/has_parameters}}
94         stasis_http_{{c_nickname}}(headers, &args, response);
95 }
96 {{/operations}}
97 {{/apis}}
98
99 {{! The rest_handler partial expands to the tree of stasis_rest_handlers }}
100 {{#root_path}}
101 {{> rest_handler}}
102 {{/root_path}}
103
104 {{#has_events}}
105 {{#events}}
106 {{> event_function_decl}}
107         )
108 {
109         RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
110         RAII_VAR(struct ast_json *, event, NULL, ast_json_unref);
111 {{#has_properties}}
112         struct ast_json *validator;
113 {{/has_properties}}
114 {{#channel}}
115         int ret;
116 {{/channel}}
117 {{#bridge}}
118 {{^channel}}
119         int ret;
120 {{/channel}}
121 {{/bridge}}
122
123 {{#channel}}
124         ast_assert(channel_snapshot != NULL);
125 {{/channel}}
126 {{#bridge}}
127         ast_assert(bridge_snapshot != NULL);
128 {{/bridge}}
129 {{#has_properties}}
130         ast_assert(blob != NULL);
131 {{#channel}}
132         ast_assert(ast_json_object_get(blob, "channel") == NULL);
133 {{/channel}}
134 {{#bridge}}
135         ast_assert(ast_json_object_get(blob, "bridge") == NULL);
136 {{/bridge}}
137         ast_assert(ast_json_object_get(blob, "type") == NULL);
138 {{#properties}}
139
140         validator = ast_json_object_get(blob, "{{name}}");
141         if (validator) {
142                 /* do validation? XXX */
143 {{#required}}
144         } else {
145                 /* fail message generation if the required parameter doesn't exist */
146                 return NULL;
147 {{/required}}
148         }
149 {{/properties}}
150
151         event = ast_json_deep_copy(blob);
152 {{/has_properties}}
153 {{^has_properties}}
154
155         event = ast_json_object_create();
156 {{/has_properties}}
157         if (!event) {
158                 return NULL;
159         }
160
161 {{#channel}}
162         ret = ast_json_object_set(event,
163                 "channel", ast_channel_snapshot_to_json(channel_snapshot));
164         if (ret) {
165                 return NULL;
166         }
167
168 {{/channel}}
169 {{#bridge}}
170         ret = ast_json_object_set(event,
171                 "bridge", ast_bridge_snapshot_to_json(bridge_snapshot));
172         if (ret) {
173                 return NULL;
174         }
175
176 {{/bridge}}
177         message = ast_json_pack("{s: o}", "{{c_id}}", ast_json_ref(event));
178         if (!message) {
179                 return NULL;
180         }
181
182         return ast_json_ref(message);
183 }
184
185 {{/events}}
186 {{/has_events}}
187 static int load_module(void)
188 {
189         stasis_app_ref();
190         return stasis_http_add_handler(&{{root_full_name}});
191 }
192
193 static int unload_module(void)
194 {
195         stasis_http_remove_handler(&{{root_full_name}});
196         stasis_app_unref();
197         return 0;
198 }
199
200 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,
201         "RESTful API module - {{{description}}}",
202         .load = load_module,
203         .unload = unload_module,
204         .nonoptreq = "res_stasis_http,res_stasis",
205         );
206 {{/api_declaration}}