Exemple #1
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
    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;
}
Exemple #10
0
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"));
}
Exemple #12
0
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);
		);
	}