Ejemplo n.º 1
0
static set* _cluster_keys(range_request* rr, apr_pool_t* pool,
                          const char* cluster)
{
    set* sections;
    sqlite3* db;
    sqlite3_stmt* stmt;
    int err;
    db = _open_db(rr);

    /* our return set */
    sections = set_new(pool, 0);


    /* prepare our select */
    err = sqlite3_prepare(db, KEYVALUE_SQL, strlen(KEYVALUE_SQL),
                          &stmt, NULL);
    if (err != SQLITE_OK) {
        range_request_warn(rr, "%s: cannot query sqlite db", cluster);
        return sections;
    }
    assert(err == SQLITE_OK);

    /* for each key/value pair in cluster */
    sqlite3_bind_text(stmt, 1, cluster, strlen(cluster), SQLITE_STATIC);
    while(sqlite3_step(stmt) == SQLITE_ROW) {
        /* add it to the return */
        const char* key = (const char*)sqlite3_column_text(stmt, 0);
        const char* value = (const char*)sqlite3_column_text(stmt, 1);
        if (NULL == value) {
            value = EMPTY_STRING;
        }
        set_add(sections, key, apr_psprintf(pool, "%s",  _substitute_dollars(pool, cluster, value) ));
    }

    /* Add the magic "KEYS" index */
    set_add(sections, "KEYS", _join_elements(pool, ',', sections));

    sqlite3_finalize(stmt);
    return sections;
}
Ejemplo n.º 2
0
/* this is where the magic happens */
static set* _cluster_keys(range_request* rr, apr_pool_t* pool,
                          const char* cluster, const char* cluster_file)
{
    apr_array_header_t* working_range;
    set* sections;
    char* section;
    char* cur_section;
    apr_pool_t* req_pool = range_request_pool(rr);
    yaml_node_t *node;
    yaml_node_t *rootnode;
    yaml_node_t *keynode;
    yaml_node_t *valuenode;
    yaml_parser_t parser;
    yaml_node_item_t *item;
    yaml_node_pair_t *pair;
    
    yaml_document_t document;
    
    FILE* fp = fopen(cluster_file, "r");

    /* make sure we can open the file and parse it */
    if (!fp) {
        range_request_warn(rr, "%s: %s not readable", cluster, cluster_file);
        return set_new(pool, 0);
    }

    if (!yaml_parser_initialize(&parser)) {
        range_request_warn(rr, "%s: cannot initialize yaml parser", cluster);
        fclose(fp);
        return set_new(pool, 0);
    }

    yaml_parser_set_input_file(&parser, fp);
    if(!yaml_parser_load(&parser, &document)) {
        range_request_warn(rr, "%s: malformatted cluster definition %s",
                           cluster, cluster_file);
        fclose(fp);
        yaml_parser_delete(&parser);
        return set_new(pool, 0);
    }
    fclose(fp);
    
    rootnode = yaml_document_get_root_node(&document);
    /* make sure it's just a simple dictionary */
    if(rootnode->type != YAML_MAPPING_NODE) {
        range_request_warn(rr, "%s: malformatted cluster definition %s",
                           cluster, cluster_file);
        yaml_document_delete(&document);
        yaml_parser_delete(&parser);
        return set_new(pool, 0);
    }

    /* "sections" refers to cluster sections - %cluster:SECTION
       it's what we're going to return */
    sections = set_new(pool, 0);
    section = cur_section = NULL;

    for(pair = rootnode->data.mapping.pairs.start;
        pair < rootnode->data.mapping.pairs.top;
        pair++) { /* these are the keys */
        keynode = yaml_document_get_node(&document, pair->key);
        /* cur_section is the keyname - the WHATEVER in %cluster:WHATEVER */
        cur_section = apr_pstrdup(pool, (char *)(keynode->data.scalar.value));
        valuenode = yaml_document_get_node(&document, pair->value);
        /* if the value is a scalar, that's our answer */
        if(valuenode->type == YAML_SCALAR_NODE) {
            set_add(sections, cur_section,
                    apr_psprintf(pool, "%s", valuenode->data.scalar.value));
        } else if (valuenode->type == YAML_SEQUENCE_NODE) {
            /* otherwise, glue together all the values in the list */
            working_range = apr_array_make(req_pool, 1, sizeof(char*));
            for(item = valuenode->data.sequence.items.start;
                item < valuenode->data.sequence.items.top;
                item++) {
                node = yaml_document_get_node(&document, (int)*item);
                if(node->type != YAML_SCALAR_NODE) { /* only scalars allowed */
                    range_request_warn(rr,
                                       "%s: malformed cluster definition %s",
                                       cluster, cluster_file);
                    yaml_document_delete(&document);
                    yaml_parser_delete(&parser);
                    return set_new(pool, 0);
                } else { /* add to the working set */
                    /* include it in () because we're going to comma it
                       together later */
                    *(char**)apr_array_push(working_range) =
                        apr_psprintf(pool, "(%s)", _substitute_dollars(pool,
                          cluster, node->data.scalar.value));
                }
            }
            /* glue the list items together with commas */
            set_add(sections, cur_section,
                    apr_array_pstrcat(pool, working_range, ','));
        }
    }

    /* Add a "KEYS" toplevel key that lists all the other keys */
    /* TODO: make an error if somebody tries to specify KEYS manually? */
    set_add(sections, "KEYS", _join_elements(pool, ',', sections));
    yaml_document_delete(&document);
    yaml_parser_delete(&parser);
    return sections;
}
Ejemplo n.º 3
0
static set* _cluster_keys(range_request* rr, apr_pool_t* pool,
                          const char* cluster, const char* cluster_file)
{
    char line[32768];
    char* p;
    int ovector[30];
    apr_array_header_t* working_range;
    set* sections;
    char* section;
    char* cur_section;
    apr_pool_t* req_pool = range_request_pool(rr);
    int line_no;
    FILE* fp = fopen(cluster_file, "r");

    if (!fp) {
        range_request_warn(rr, "%s: %s not readable", cluster, cluster_file);
        return set_new(pool, 0);
    }

    if (!include_re) {
        const char* error;
        include_re = pcre_compile(INCLUDE_RE, 0, &error, ovector, NULL);
        assert(include_re);

        exclude_re = pcre_compile(EXCLUDE_RE, 0, &error, ovector, NULL);
        assert(exclude_re);
    }

    sections = set_new(pool, 0);
    section = cur_section = NULL;


    working_range = apr_array_make(req_pool, 1, sizeof(char*));
    line_no = 0;
    while (fgets(line, sizeof line, fp)) {
        int len;
        int count;
        line_no++;
        line[sizeof line - 1] = '\0';
        len = strlen(line);
        if (len+1 >= sizeof(line) && line[len - 1] != '\n') {
            /* incomplete line */
            fprintf(stderr, "%s:%d lines > 32767 chars not supported\n", cluster_file, line_no);
            exit(-1);
        }

        line[--len] = '\0'; /* get rid of the \n */
        for (p = line; *p; ++p)
            if (*p == '#') {
                *p = '\0';
                break;
            }

        len = strlen(line);
        if (len == 0) continue;

        for (p = &line[len - 1]; isspace(*p); --p) {
            *p = '\0';
            --len;
        }

        if (!*line) continue;

        if (!(isspace(*line))) {
            cur_section = apr_pstrdup(pool, line);
            continue;
        }

        if (section && strcmp(cur_section, section) != 0) {
            set_add(sections, section, 
                    apr_array_pstrcat(pool, working_range, ','));
            working_range = apr_array_make(req_pool, 1, sizeof(char*));
        }

        section = cur_section;
        count = pcre_exec(include_re, NULL, line, len,
                          0, 0, ovector, 30);
        if (count > 0) {
            line[ovector[3]] = '\0';
            *(char**)apr_array_push(working_range) =
                apr_psprintf(pool, "(%s)",
                             _substitute_dollars(pool, cluster, &line[ovector[2]]));
            continue;
        }

        count = pcre_exec(exclude_re, NULL, line, len,
                          0, 0, ovector, 30);
        if (count > 0) {
            line[ovector[3]] = '\0';
            *(char**)apr_array_push(working_range) =
                apr_psprintf(pool, "-(%s)",
                             _substitute_dollars(pool, cluster, &line[ovector[2]]));
        }

    }
    fclose(fp);

    if (cur_section)
        set_add(sections, cur_section,
                apr_array_pstrcat(pool, working_range, ','));

    set_add(sections, "KEYS", _join_elements(pool, ',', sections));
    set_add(sections, "UP", set_get_data(sections, "CLUSTER"));
    if (set_get(sections, "ALL") && set_get(sections, "CLUSTER"))
        set_add(sections, "DOWN",
                apr_psprintf(pool, "(%s)-(%s)",
                             (char*)set_get_data(sections, "ALL"),
                             (char*)set_get_data(sections, "CLUSTER")));
    return sections;
}