ARI: Fix endpoint/channel subscription issues; allow for subscriptions to tech
[asterisk/asterisk.git] / res / ari / resource_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 /*! \file
20  *
21  * \brief /api-docs/endpoints.{format} implementation- Endpoint resources
22  *
23  * \author David M. Lee, II <dlee@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "resource_endpoints.h"
31
32 #include "asterisk/astobj2.h"
33 #include "asterisk/stasis.h"
34 #include "asterisk/stasis_app.h"
35 #include "asterisk/stasis_endpoints.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/message.h"
38
39 void ast_ari_endpoints_list(struct ast_variable *headers,
40         struct ast_ari_endpoints_list_args *args,
41         struct ast_ari_response *response)
42 {
43         RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup);
44         RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
45         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
46         struct ao2_iterator i;
47         void *obj;
48
49         cache = ast_endpoint_cache();
50         if (!cache) {
51                 ast_ari_response_error(
52                         response, 500, "Internal Server Error",
53                         "Message bus not initialized");
54                 return;
55         }
56         ao2_ref(cache, +1);
57
58         snapshots = stasis_cache_dump(cache, ast_endpoint_snapshot_type());
59         if (!snapshots) {
60                 ast_ari_response_alloc_failed(response);
61                 return;
62         }
63
64         json = ast_json_array_create();
65         if (!json) {
66                 ast_ari_response_alloc_failed(response);
67                 return;
68         }
69
70         i = ao2_iterator_init(snapshots, 0);
71         while ((obj = ao2_iterator_next(&i))) {
72                 RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup);
73                 struct ast_endpoint_snapshot *snapshot = stasis_message_data(msg);
74                 struct ast_json *json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
75
76                 if (!json_endpoint || ast_json_array_append(json, json_endpoint)) {
77                         ao2_iterator_destroy(&i);
78                         ast_ari_response_alloc_failed(response);
79                         return;
80                 }
81         }
82         ao2_iterator_destroy(&i);
83
84         ast_ari_response_ok(response, ast_json_ref(json));
85 }
86
87 void ast_ari_endpoints_list_by_tech(struct ast_variable *headers,
88         struct ast_ari_endpoints_list_by_tech_args *args,
89         struct ast_ari_response *response)
90 {
91         RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup);
92         RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
93         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
94         struct ast_endpoint *tech_endpoint;
95         struct ao2_iterator i;
96         void *obj;
97
98         tech_endpoint = ast_endpoint_find_by_id(args->tech);
99         if (!tech_endpoint) {
100                 ast_ari_response_error(response, 404, "Not Found",
101                                        "No Endpoints found - invalid tech %s", args->tech);
102                 return;
103         }
104         ao2_ref(tech_endpoint, -1);
105
106         cache = ast_endpoint_cache();
107         if (!cache) {
108                 ast_ari_response_error(
109                         response, 500, "Internal Server Error",
110                         "Message bus not initialized");
111                 return;
112         }
113         ao2_ref(cache, +1);
114
115         snapshots = stasis_cache_dump(cache, ast_endpoint_snapshot_type());
116         if (!snapshots) {
117                 ast_ari_response_alloc_failed(response);
118                 return;
119         }
120
121         json = ast_json_array_create();
122         if (!json) {
123                 ast_ari_response_alloc_failed(response);
124                 return;
125         }
126
127         i = ao2_iterator_init(snapshots, 0);
128         while ((obj = ao2_iterator_next(&i))) {
129                 RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup);
130                 struct ast_endpoint_snapshot *snapshot = stasis_message_data(msg);
131                 struct ast_json *json_endpoint;
132                 int r;
133
134                 if (strcasecmp(args->tech, snapshot->tech) != 0) {
135                         continue;
136                 }
137
138                 json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
139                 if (!json_endpoint) {
140                         continue;
141                 }
142
143                 r = ast_json_array_append(
144                         json, json_endpoint);
145                 if (r != 0) {
146                         ao2_iterator_destroy(&i);
147                         ast_ari_response_alloc_failed(response);
148                         return;
149                 }
150         }
151         ao2_iterator_destroy(&i);
152         ast_ari_response_ok(response, ast_json_ref(json));
153 }
154
155 void ast_ari_endpoints_get(struct ast_variable *headers,
156         struct ast_ari_endpoints_get_args *args,
157         struct ast_ari_response *response)
158 {
159         struct ast_json *json;
160         RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup);
161
162         snapshot = ast_endpoint_latest_snapshot(args->tech, args->resource);
163         if (!snapshot) {
164                 ast_ari_response_error(response, 404, "Not Found",
165                         "Endpoint not found");
166                 return;
167         }
168
169         json = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer());
170         if (!json) {
171                 ast_ari_response_alloc_failed(response);
172                 return;
173         }
174
175         ast_ari_response_ok(response, json);
176 }