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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>