static json_object_t opensensordata_cache_get(opensensordata_t* osd, const char* name) { int err; char buffer[512]; char filename[512]; if ((osd->cache == NULL) || (strlen(osd->cache) == 0)) { log_err("OpenSensorData: Invalid cache dir."); return json_null(); } opensensordata_get_cache_file(osd, name, filename, 512); json_object_t def = json_load(filename, &err, buffer, 512); if (err) { log_err("%s", buffer); json_unref(def); return json_null(); } else if (!json_isobject(def)) { log_err("OpenSensorData: Invalid definition: %s", filename); json_unref(def); return json_null(); } // Check whether the response was an error object. json_object_t e = json_object_get(def, "error"); if (!json_isnull(e)) { const char* msg = json_object_getstr(def, "msg"); log_err("OpenSensorData: Server returned an error: %s", msg); json_unref(def); return json_null(); } return def; }
const char* osd_object_get_name(json_object_t obj) { json_object_t v = json_object_get(obj, "name"); if (json_isstring(v)) return json_string_value(v); if (json_isnull(v)) { log_err("OpenSensorData: Object has no name!"); } else { log_err("OpenSensorData: Object name is not a string!"); } return NULL; }
static int opensensordata_get_cached_id(opensensordata_t* osd, const char* name) { json_object_t def = opensensordata_cache_get(osd, name); if (json_isnull(def)) { return -1; } int id = osd_object_get_id(def); json_unref(def); if (id == -1) log_err("OpenSensorData: Invalid cache object: %s", name); return id; }
int osd_object_get_id(json_object_t obj) { int id = -1; json_object_t v = json_object_get(obj, "id"); if (json_isnull(v)) { log_err("OpenSensorData: Object has no ID"); return -1; } if (json_isstring(v)) { id = atoi(json_string_value(v)); } else if (json_isnumber(v)) { id = json_number_value(v); } else { log_err("OpenSensorData: ID value is not a string nor a number!"); return -1; } return id; }
static int process_json(bgpstream_broker_datasource_t *broker_ds, bgpstream_input_mgr_t *input_mgr, const char *js, jsmntok_t *root_tok, size_t count) { int i, j, k; jsmntok_t *t = root_tok + 1; int arr_len, obj_len; int time_set = 0; int num_results = 0; // per-file info char *url = NULL; size_t url_len = 0; int url_set = 0; char collector[BGPSTREAM_UTILS_STR_NAME_LEN] = ""; int collector_set = 0; char project[BGPSTREAM_UTILS_STR_NAME_LEN] = ""; int project_set = 0; char type[BGPSTREAM_UTILS_STR_NAME_LEN] = ""; int type_set = 0; uint32_t initial_time = 0; int initial_time_set = 0; uint32_t duration = 0; int duration_set = 0; if (count == 0) { fprintf(stderr, "ERROR: Empty JSON response from broker\n"); goto retry; } if (root_tok->type != JSMN_OBJECT) { fprintf(stderr, "ERROR: Root object is not JSON\n"); fprintf(stderr, "INFO: JSON: %s\n", js); goto err; } // iterate over the children of the root object for (i = 0; i < root_tok->size; i++) { // all keys must be strings if (t->type != JSMN_STRING) { fprintf(stderr, "ERROR: Encountered non-string key: '%.*s'\n", t->end - t->start, js + t->start); goto err; } if (json_strcmp(js, t, "time") == 0) { NEXT_TOK; json_type_assert(t, JSMN_PRIMITIVE); json_strtoul(broker_ds->last_response_time, t); time_set = 1; NEXT_TOK; } else if (json_strcmp(js, t, "type") == 0) { NEXT_TOK; json_str_assert(js, t, "data"); NEXT_TOK; } else if (json_strcmp(js, t, "error") == 0) { NEXT_TOK; if (json_isnull(js, t) == 0) { // i.e. there is an error set fprintf(stderr, "ERROR: Broker reported an error: %.*s\n", t->end - t->start, js + t->start); goto err; } NEXT_TOK; } else if (json_strcmp(js, t, "queryParameters") == 0) { NEXT_TOK; json_type_assert(t, JSMN_OBJECT); // skip over this object t = json_skip(t); } else if (json_strcmp(js, t, "data") == 0) { NEXT_TOK; json_type_assert(t, JSMN_OBJECT); NEXT_TOK; json_str_assert(js, t, "dumpFiles"); NEXT_TOK; json_type_assert(t, JSMN_ARRAY); arr_len = t->size; // number of dump files NEXT_TOK; // first elem in array for (j = 0; j < arr_len; j++) { json_type_assert(t, JSMN_OBJECT); obj_len = t->size; NEXT_TOK; url_set = 0; project_set = 0; collector_set = 0; type_set = 0; initial_time_set = 0; duration_set = 0; for (k = 0; k < obj_len; k++) { if (json_strcmp(js, t, "urlType") == 0) { NEXT_TOK; if (json_strcmp(js, t, "simple") != 0) { // not yet supported? fprintf(stderr, "ERROR: Unsupported URL type '%.*s'\n", t->end - t->start, js + t->start); goto err; } NEXT_TOK; } else if (json_strcmp(js, t, "url") == 0) { NEXT_TOK; json_type_assert(t, JSMN_STRING); if (url_len < (t->end - t->start + 1)) { url_len = t->end - t->start + 1; if ((url = realloc(url, url_len)) == NULL) { fprintf(stderr, "ERROR: Could not realloc URL string\n"); goto err; } } json_strcpy(url, t, js); unescape_url(url); url_set = 1; NEXT_TOK; } else if (json_strcmp(js, t, "project") == 0) { NEXT_TOK; json_type_assert(t, JSMN_STRING); json_strcpy(project, t, js); project_set = 1; NEXT_TOK; } else if (json_strcmp(js, t, "collector") == 0) { NEXT_TOK; json_type_assert(t, JSMN_STRING); json_strcpy(collector, t, js); collector_set = 1; NEXT_TOK; } else if (json_strcmp(js, t, "type") == 0) { NEXT_TOK; json_type_assert(t, JSMN_STRING); json_strcpy(type, t, js); type_set = 1; NEXT_TOK; } else if (json_strcmp(js, t, "initialTime") == 0) { NEXT_TOK; json_type_assert(t, JSMN_PRIMITIVE); json_strtoul(initial_time, t); initial_time_set = 1; NEXT_TOK; } else if (json_strcmp(js, t, "duration") == 0) { NEXT_TOK; json_type_assert(t, JSMN_PRIMITIVE); json_strtoul(duration, t); duration_set = 1; NEXT_TOK; } else { fprintf(stderr, "ERROR: Unknown field '%.*s'\n", t->end - t->start, js + t->start); goto err; } } // file obj has been completely read if (url_set == 0 || project_set == 0 || collector_set == 0 || type_set == 0 || initial_time_set == 0 || duration_set == 0) { fprintf(stderr, "ERROR: Invalid dumpFile record\n"); goto retry; } #ifdef WITH_BROKER_DEBUG fprintf(stderr, "----------\n"); fprintf(stderr, "URL: %s\n", url); fprintf(stderr, "Project: %s\n", project); fprintf(stderr, "Collector: %s\n", collector); fprintf(stderr, "Type: %s\n", type); fprintf(stderr, "InitialTime: %" PRIu32 "\n", initial_time); fprintf(stderr, "Duration: %" PRIu32 "\n", duration); #endif // do we need to update our current_window_end? if (initial_time + duration > broker_ds->current_window_end) { broker_ds->current_window_end = (initial_time + duration); } if (bgpstream_input_mgr_push_sorted_input( input_mgr, strdup(url), strdup(project), strdup(collector), strdup(type), initial_time, duration) <= 0) { goto err; } num_results++; } } // TODO: handle unknown tokens } if (time_set == 0) { goto err; } free(url); return num_results; retry: free(url); return ERR_RETRY; err: fprintf(stderr, "ERROR: Invalid JSON response received from broker\n"); free(url); return ERR_RETRY; }