static GError * _local_client_execute_batch (struct oio_sqlx_client_s *self, struct oio_sqlx_batch_s *batch, struct oio_sqlx_batch_result_s **out_result) { /* sanity checks */ if (!self || !batch || !out_result || !batch->statements) return BADREQ("Invalid parameter"); const guint max = batch->statements->len; if (!max) return BADREQ("Empty batch"); for (guint i=0; i<max ;++i) { GPtrArray *stmt = batch->statements->pdata[i]; if (!stmt || stmt->len < 1) return BADREQ("Empty statement at %u", i); } struct oio_sqlx_client_LOCAL_s *s = (struct oio_sqlx_client_LOCAL_s*)self; g_assert (s->vtable == &vtable_LOCAL); g_assert (s->db != NULL); struct oio_sqlx_batch_result_s *result = oio_sqlx_batch_result__create (); for (guint i=0; i<max ;++i) { GPtrArray *stmt = batch->statements->pdata[i]; struct oio_sqlx_statement_result_s *out = oio_sqlx_statement_result__create (); _exec_statement (s, stmt, out); g_ptr_array_add (result->results, out); } *out_result = result; return NULL; }
enum http_rc_e action_forward_stats (struct req_args_s *args) { const char *id = OPT("id"); if (!id) return _reply_format_error (args, BADREQ("Missing SRVID")); args->rp->no_access(); MESSAGE req = metautils_message_create_named("REQ_STATS"); GByteArray *encoded = message_marshall_gba_and_clean (req); gchar *packed = NULL; GError *err = gridd_client_exec_and_concat_string (id, 1.0, encoded, &packed); if (err) { g_free0 (packed); if (CODE_IS_NETWORK_ERROR(err->code)) { if (err->code == ERRCODE_CONN_TIMEOUT || err->code == ERRCODE_READ_TIMEOUT) return _reply_gateway_timeout (args, err); return _reply_srv_unavailable (args, err); } return _reply_common_error (args, err); } for (gchar *s=packed; *s ;++s) { if (*s == '=') *s = ' '; } /* TODO(jfs): quite duplicated from _reply_json() but the original was not suitable. */ args->rp->set_status (200, "OK"); args->rp->set_body_bytes (g_bytes_new_take((guint8*)packed, strlen(packed))); args->rp->finalize (); return HTTPRC_DONE; }
static int _meta2_filter_check_ns_name(struct gridd_filter_ctx_s *ctx, struct gridd_reply_ctx_s *reply, int optional) { (void) reply; TRACE_FILTER(); const struct meta2_backend_s *backend = meta2_filter_ctx_get_backend(ctx); const char *req_ns = oio_url_get(meta2_filter_ctx_get_url(ctx), OIOURL_NS); if (!backend || !backend->ns_name[0]) { GRID_DEBUG("Missing information for namespace checking"); meta2_filter_ctx_set_error(ctx, SYSERR("backend not ready")); return FILTER_KO; } if (!req_ns) { if (optional) return FILTER_OK; GRID_DEBUG("Missing namespace name in request"); meta2_filter_ctx_set_error(ctx, BADREQ("No namespace")); return FILTER_KO; } if (0 != g_ascii_strcasecmp(backend->ns_name, req_ns)) { meta2_filter_ctx_set_error(ctx, BADNS()); return FILTER_KO; } return FILTER_OK; }
static GError * _get_peers(struct sqlx_service_s *ss, struct sqlx_name_s *n, gboolean nocache, gchar ***result) { EXTRA_ASSERT(ss != NULL); EXTRA_ASSERT(result != NULL); gint retries = 1; gchar **peers = NULL; GError *err = NULL; gint64 seq = 1; struct oio_url_s *u = oio_url_empty (); oio_url_set(u, OIOURL_NS, ss->ns_name); if (!sqlx_name_extract (n, u, NAME_SRVTYPE_META2, &seq)) { oio_url_pclean (&u); return BADREQ("Invalid type name: '%s'", n->type); } retry: if (nocache) { hc_decache_reference_service(ss->resolver, u, n->type); if (!result) { oio_url_pclean (&u); return NULL; } } peers = NULL; err = hc_resolve_reference_service(ss->resolver, u, n->type, &peers); if (NULL != err) { g_prefix_error(&err, "Peer resolution error: "); oio_url_clean(u); return err; } gchar **out = filter_services_and_clean(ss, peers, seq, n->type); if (!out) { if (retries-- > 0) { nocache = TRUE; goto retry; } err = NEWERROR(CODE_CONTAINER_NOTFOUND, "Base not managed"); } if (err) { if (out) g_strfreev (out); *result = NULL; } else { *result = out; } oio_url_clean(u); return err; }
int meta2_filter_check_url_cid (struct gridd_filter_ctx_s *ctx, struct gridd_reply_ctx_s *reply) { (void) reply; struct oio_url_s *url = meta2_filter_ctx_get_url(ctx); TRACE_FILTER(); if (url && oio_url_has(url, OIOURL_HEXID)) return FILTER_OK; meta2_filter_ctx_set_error (ctx, BADREQ("Invalid URL")); return FILTER_KO; }
static GError * decode_json_string_array (gchar *** pkeys, struct json_object *j) { gchar **keys = NULL; GError *err = NULL; if (json_object_is_type (j, json_type_null)) { *pkeys = g_malloc0(sizeof(void*)); return NULL; } // Parse the keys if (!json_object_is_type (j, json_type_array)) return BADREQ ("Invalid/Unexpected JSON"); GPtrArray *v = g_ptr_array_new (); guint count = 0; for (gint i = json_object_array_length (j); i > 0; --i) { ++count; struct json_object *item = json_object_array_get_idx (j, i - 1); if (!json_object_is_type (item, json_type_string)) { err = BADREQ ("Invalid string at [%u]", count); break; } g_ptr_array_add (v, g_strdup (json_object_get_string (item))); } if (!err) { g_ptr_array_add (v, NULL); keys = (gchar **) g_ptr_array_free (v, FALSE); } else { g_ptr_array_free (v, TRUE); } *pkeys = keys; return err; }
enum http_rc_e action_cs_put (struct req_args_s *args) { struct json_tokener *parser; struct json_object *jbody; enum http_rc_e rc; parser = json_tokener_new (); jbody = json_tokener_parse_ex (parser, (char *) args->rq->body->data, args->rq->body->len); if (!json_object_is_type (jbody, json_type_object)) rc = _reply_format_error (args, BADREQ ("Invalid srv")); else rc = _registration (args, REGOP_PUSH, jbody); json_object_put (jbody); json_tokener_free (parser); return rc; }
GError * meta1_backend_init(struct meta1_backend_s **out, const char *ns, struct sqlx_repository_s *repo, struct grid_lbpool_s *glp) { EXTRA_ASSERT(out != NULL); EXTRA_ASSERT(repo != NULL); EXTRA_ASSERT(glp != NULL); if (!*ns || strlen(ns) >= LIMIT_LENGTH_NSNAME) return BADREQ("Invalid namespace name"); struct meta1_backend_s *m1 = g_malloc0(sizeof(*m1)); g_strlcpy (m1->ns_name, ns, sizeof(m1->ns_name)); m1->type = NAME_SRVTYPE_META1; m1->lb = glp; m1->repo = repo; m1->prefixes = meta1_prefixes_init(); m1->svcupdate = service_update_policies_create(); *out = m1; return NULL; }
GError * oio_events_queue_factory__create_beanstalkd (const char *endpoint, struct oio_events_queue_s **out) { EXTRA_ASSERT(endpoint != NULL); EXTRA_ASSERT(out != NULL); *out = NULL; if (!metautils_url_valid_for_connect (endpoint)) return BADREQ("Invalid beanstalkd endpoint [%s]", endpoint); struct _queue_BEANSTALKD_s *self = g_malloc0 (sizeof(*self)); self->vtable = &vtable_BEANSTALKD; self->queue = g_async_queue_new (); self->tube = g_strdup(OIO_EVT_BEANSTALKD_DEFAULT_TUBE); self->max_events_in_queue = OIO_EVTQ_MAXPENDING; self->endpoint = g_strdup (endpoint); oio_events_queue_buffer_init(&(self->buffer), 1 * G_TIME_SPAN_SECOND); *out = (struct oio_events_queue_s*) self; return NULL; }
static enum http_rc_e _registration (struct req_args_s *args, enum reg_op_e op, struct json_object *jsrv) { GError *err; if (!jsrv || !json_object_is_type (jsrv, json_type_object)) return _reply_common_error (args, BADREQ("Expected: json object")); if (!push_queue) return _reply_bad_gateway(args, NEWERROR(CODE_INTERNAL_ERROR, "Service upstream disabled")); if (NULL != (err = _cs_check_tokens(args))) return _reply_notfound_error (args, err); struct service_info_s *si = NULL; err = service_info_load_json_object (jsrv, &si, TRUE); if (err) { if (err->code == CODE_BAD_REQUEST) return _reply_format_error (args, err); else return _reply_system_error (args, err); } if (!si->type[0]) { service_info_clean (si); return _reply_format_error (args, BADREQ("Service type not specified")); } if (!si->ns_name[0]) { g_strlcpy (si->ns_name, nsname, sizeof(si->ns_name)); } else if (!validate_namespace (si->ns_name)) { service_info_clean (si); return _reply_format_error (args, NEWERROR (CODE_NAMESPACE_NOTMANAGED, "Unexpected NS")); } si->score.timestamp = oio_ext_real_time () / G_TIME_SPAN_SECOND; if (op == REGOP_PUSH) si->score.value = SCORE_UNSET; else if (op == REGOP_UNLOCK) si->score.value = SCORE_UNLOCK; else /* if (op == REGOP_LOCK) */ si->score.value = CLAMP(si->score.value, SCORE_DOWN, SCORE_MAX); // TODO follow the DRY principle and factorize this! if (flag_cache_enabled) { GString *gstr = g_string_new (""); service_info_encode_json (gstr, si, TRUE); PUSH_DO(lru_tree_insert(push_queue, service_info_key(si), si)); return _reply_success_json (args, gstr); } else { CSURL(cs); GSList l = {.data = si, .next = NULL}; if (NULL != (err = conscience_remote_push_services (cs, &l))) { service_info_clean (si); return _reply_common_error (args, err); } else { GString *gstr = g_string_new (""); service_info_encode_json (gstr, si, TRUE); service_info_clean (si); return _reply_success_json (args, gstr); } } }
enum http_rc_e action_forward (struct req_args_s *args) { const char *id = OPT("id"); const char *action = TOK("ACTION"); if (!id) return _reply_format_error (args, BADREQ("Missing SRVID")); if (!action) return _reply_format_error (args, BADREQ("Missing action")); GError *err = NULL; if (!g_ascii_strcasecmp (action, "flush")) { err = sqlx_remote_execute_FLUSH (id); if (!err) return _reply_success_json (args, NULL); return _reply_common_error (args, err); } if (!g_ascii_strcasecmp (action, "reload")) { err = sqlx_remote_execute_RELOAD (id); if (!err) return _reply_success_json (args, NULL); return _reply_common_error (args, err); } if (!g_ascii_strcasecmp (action, "kill")) { GByteArray *encoded = message_marshall_gba_and_clean ( metautils_message_create_named("REQ_KILL")); err = gridd_client_exec (id, 1.0, encoded); if (err) return _reply_common_error (args, err); return _reply_success_json (args, NULL); } if (!g_ascii_strcasecmp (action, "ping")) { args->rp->no_access(); GByteArray *encoded = message_marshall_gba_and_clean ( metautils_message_create_named("REQ_PING")); err = gridd_client_exec (id, 1.0, encoded); if (err) return _reply_common_error (args, err); return _reply_success_json (args, NULL); } if (!g_ascii_strcasecmp (action, "lean-glib")) { MESSAGE req = metautils_message_create_named("REQ_LEAN"); metautils_message_add_field_str(req, "LIBC", "1"); metautils_message_add_field_str(req, "THREADS", "1"); GByteArray *encoded = message_marshall_gba_and_clean (req); err = gridd_client_exec (id, 1.0, encoded); if (err) return _reply_common_error (args, err); return _reply_success_json (args, NULL); } if (!g_ascii_strcasecmp (action, "lean-sqlx")) { GByteArray *encoded = message_marshall_gba_and_clean ( metautils_message_create_named(NAME_MSGNAME_SQLX_LEANIFY)); err = gridd_client_exec (id, 1.0, encoded); if (err) return _reply_common_error (args, err); return _reply_success_json (args, NULL); } if (!g_ascii_strcasecmp (action, "version")) { args->rp->no_access(); MESSAGE req = metautils_message_create_named("REQ_VERSION"); GByteArray *encoded = message_marshall_gba_and_clean (req); gchar *packed = NULL; err = gridd_client_exec_and_concat_string (id, 1.0, encoded, &packed); if (err) { g_free0 (packed); return _reply_common_error (args, err); } /* TODO(jfs): quite duplicated from _reply_json() but the original was not suitable. */ args->rp->set_status (200, "OK"); args->rp->set_body_bytes (g_bytes_new_take((guint8*)packed, strlen(packed))); args->rp->finalize (); return HTTPRC_DONE; } if (!g_ascii_strcasecmp (action, "handlers")) { args->rp->no_access(); MESSAGE req = metautils_message_create_named("REQ_HANDLERS"); GByteArray *encoded = message_marshall_gba_and_clean (req); gchar *packed = NULL; err = gridd_client_exec_and_concat_string (id, 1.0, encoded, &packed); if (err) { g_free0 (packed); return _reply_common_error (args, err); } /* TODO(jfs): quite duplicated from _reply_json() but the original was not suitable. */ args->rp->set_status (200, "OK"); args->rp->set_body_bytes (g_bytes_new_take((guint8*)packed, strlen(packed))); args->rp->finalize (); return HTTPRC_DONE; } return _reply_common_error (args, BADREQ("unexpected action")); }
static enum http_rc_e _registration (struct req_args_s *args, enum reg_op_e op, struct json_object *jsrv) { GError *err; if (!jsrv || !json_object_is_type (jsrv, json_type_object)) return _reply_common_error (args, BADREQ("Expected: json object")); if (!push_queue) return _reply_bad_gateway(args, SYSERR("Service upstream disabled")); if (NULL != (err = _cs_check_tokens(args))) return _reply_notfound_error (args, err); struct service_info_s *si = NULL; err = service_info_load_json_object (jsrv, &si, TRUE); if (err) { g_prefix_error (&err, "JSON error: "); if (err->code == CODE_BAD_REQUEST) return _reply_format_error (args, err); else return _reply_system_error (args, err); } if (!si->type[0]) { service_info_clean (si); return _reply_format_error (args, BADREQ("Service type not specified")); } if (!si->ns_name[0]) { GRID_TRACE2("%s NS forced to %s", __FUNCTION__, si->ns_name); g_strlcpy (si->ns_name, nsname, sizeof(si->ns_name)); } else if (!validate_namespace (si->ns_name)) { service_info_clean (si); return _reply_format_error (args, BADNS()); } gchar *k = service_info_key (si); STRING_STACKIFY(k); GRID_TRACE2("%s op=%s score=%d key=[%s]", __FUNCTION__, _regop_2str(op), si->score.value, k); switch (op) { case REGOP_PUSH: si->score.value = SCORE_UNSET; if (!service_is_known (k)) { service_learn (k); service_tag_set_value_boolean (service_info_ensure_tag ( si->tags, NAME_TAGNAME_RAWX_FIRST), TRUE); } break; case REGOP_LOCK: si->score.value = CLAMP(si->score.value, SCORE_DOWN, SCORE_MAX); break; case REGOP_UNLOCK: si->score.value = SCORE_UNLOCK; break; default: g_assert_not_reached(); } if (cs_expire_local_services > 0) { struct service_info_s *v = service_info_dup (si); v->score.timestamp = oio_ext_monotonic_seconds (); PUSH_DO( const struct service_info_s *si0 = lru_tree_get(srv_registered, k); if (si0) v->score.value = si0->score.value; lru_tree_insert (srv_registered, g_strdup(k), v); ); }