sw-collector: Check for epoch-less Debian package versions
[strongswan.git] / src / libimcv / plugins / imc_swima / sw_collector / sw_collector_rest_api.c
1 /*
2 * Copyright (C) 2017 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "sw_collector_rest_api.h"
17
18 #include <rest/rest.h>
19 #include <utils/debug.h>
20
21 typedef struct private_sw_collector_rest_api_t private_sw_collector_rest_api_t;
22
23 /**
24 * Private data of an sw_collector_rest_api_t object.
25 */
26 struct private_sw_collector_rest_api_t {
27
28 /**
29 * Public members of sw_collector_rest_api_state_t
30 */
31 sw_collector_rest_api_t public;
32
33 /**
34 * Software collector database
35 */
36 sw_collector_db_t *db;
37
38 /**
39 * REST API of central collector database
40 */
41 rest_t *rest_api;
42
43 };
44
45 /**
46 * Put all locally retrieved software identifiers into a json object
47 */
48 static json_object* create_rest_request(private_sw_collector_rest_api_t *this,
49 sw_collector_db_query_t type)
50 {
51 json_object *jrequest, *jarray, *jstring;
52 char *name, *package, *version;
53 uint32_t sw_id, i;
54 enumerator_t *e;
55
56 jrequest = json_object_new_object();
57 jarray = json_object_new_array();
58 json_object_object_add(jrequest, "data", jarray);
59
60 e = this->db->create_sw_enumerator(this->db, type, NULL);
61 if (!e)
62 {
63 return NULL;
64 }
65 while (e->enumerate(e, &sw_id, &name, &package, &version, &i))
66 {
67 jstring = json_object_new_string(name);
68 json_object_array_add(jarray, jstring);
69 }
70 e->destroy(e);
71
72 return jrequest;
73 }
74
75 typedef struct {
76 /** public enumerator interface */
77 enumerator_t public;
78 /** enumerated json array */
79 json_object *jarray;
80 /** current index +1, initialized at 0 */
81 int idx;
82 } json_array_enumerator_t;
83
84 METHOD(enumerator_t, enumerate, bool,
85 json_array_enumerator_t *this, va_list args)
86 {
87 json_object *jvalue;
88 char **out;
89
90 VA_ARGS_VGET(args, out);
91
92 if (this->idx >= json_object_array_length(this->jarray))
93 {
94 return FALSE;
95 }
96
97 jvalue = json_object_array_get_idx(this->jarray, this->idx++);
98 if (json_object_get_type(jvalue) != json_type_string)
99 {
100 DBG1(DBG_IMC, "json_string element expected in json_array");
101 return FALSE;
102 }
103 *out = (char*)json_object_get_string(jvalue);
104
105 return TRUE;
106 }
107
108 METHOD(enumerator_t, enumerator_destroy, void,
109 json_array_enumerator_t *this)
110 {
111 json_object_put(this->jarray);
112 free(this);
113 }
114
115 METHOD(sw_collector_rest_api_t, create_sw_enumerator, enumerator_t*,
116 private_sw_collector_rest_api_t *this, sw_collector_db_query_t type)
117 {
118 json_array_enumerator_t *enumerator;
119 json_object *jrequest, *jresponse;
120 char cmd[BUF_LEN];
121 status_t status;
122
123 jrequest = create_rest_request(this, type);
124 if (!jrequest)
125 {
126 return NULL;
127 }
128 snprintf(cmd, BUF_LEN, "sessions/0/swid-measurement/");
129
130 status = this->rest_api->post(this->rest_api, cmd, jrequest, &jresponse);
131 json_object_put(jrequest);
132
133 switch (status)
134 {
135 case SUCCESS:
136 case NOT_FOUND:
137 jresponse = json_object_new_array();
138 break;
139 case NEED_MORE:
140 if (json_object_get_type(jresponse) != json_type_array)
141 {
142 DBG1(DBG_IMC, "REST response was not a json_array");
143 json_object_put(jresponse);
144 return NULL;
145 }
146 break;
147 case FAILED:
148 default:
149 return NULL;
150 }
151
152 INIT(enumerator,
153 .public = {
154 .enumerate = enumerator_enumerate_default,
155 .venumerate = _enumerate,
156 .destroy = _enumerator_destroy,
157 },
158 .jarray = jresponse,
159 );
160
161 return &enumerator->public;
162 }
163
164 METHOD(sw_collector_rest_api_t, destroy, void,
165 private_sw_collector_rest_api_t *this)
166 {
167 this->rest_api->destroy(this->rest_api);
168 free(this);
169 }
170
171 /**
172 * Described in header.
173 */
174 sw_collector_rest_api_t *sw_collector_rest_api_create(sw_collector_db_t *db)
175 {
176 private_sw_collector_rest_api_t *this;
177 int timeout;
178 char *uri;
179
180 uri = lib->settings->get_str(lib->settings, "%s.rest_api.uri", NULL,
181 lib->ns);
182 timeout = lib->settings->get_int(lib->settings, "%s.rest_api.timeout", 120,
183 lib->ns);
184 if (!uri)
185 {
186 DBG1(DBG_IMC, "REST URI to central collector database not set");
187 return NULL;
188 }
189
190 INIT(this,
191 .public = {
192 .create_sw_enumerator = _create_sw_enumerator,
193 .destroy = _destroy,
194 },
195 .db = db,
196 .rest_api = rest_create(uri, timeout),
197 );
198
199 return &this->public;
200 }