Exemplo n.º 1
0
/**
 * Sets the error status on a new composed field.
 */
static void qd_set_response_status(const qd_amqp_error_t *error, qd_composed_field_t **field)
{
    //
    // Insert appropriate success or error
    //
    *field = qd_compose(QD_PERFORMATIVE_APPLICATION_PROPERTIES, *field);
    qd_compose_start_map(*field);

    qd_compose_insert_string(*field, status_description);
    qd_compose_insert_string(*field, error->description);

    qd_compose_insert_string(*field, status_code);
    qd_compose_insert_uint(*field, error->status);

    qd_compose_end_map(*field);
}
Exemplo n.º 2
0
static void qd_core_agent_query_handler(qdr_core_t                 *core,
                                        qd_router_entity_type_t     entity_type,
                                        qd_router_operation_type_t  operation_type,
                                        qd_message_t               *msg,
                                        int                        *count,
                                        int                        *offset)
{
    //
    // Add the Body.
    //
    qd_composed_field_t *field = qd_compose(QD_PERFORMATIVE_BODY_AMQP_VALUE, 0);

    // Start a map in the body. Look for the end map in the callback function, qd_manage_response_handler.
    qd_compose_start_map(field);

    //add a "attributeNames" key
    qd_compose_insert_string(field, ATTRIBUTE_NAMES);

    // Call local function that creates and returns a local qd_management_context_t object containing the values passed in.
    qd_management_context_t *ctx = qd_management_context(qd_message(), msg, field, 0, core, operation_type, (*count));

    // Grab the attribute names from the incoming message body. The attribute names will be used later on in the response.
    qd_parsed_field_t *attribute_names_parsed_field = 0;

    qd_field_iterator_t *body_iter = qd_message_field_iterator(msg, QD_FIELD_BODY);

    qd_parsed_field_t *body = qd_parse(body_iter);
    if (body != 0 && qd_parse_is_map(body)) {
        attribute_names_parsed_field = qd_parse_value_by_key(body, ATTRIBUTE_NAMES);
    }

    // Set the callback function.
    qdr_manage_handler(core, qd_manage_response_handler);
    ctx->query = qdr_manage_query(core, ctx, entity_type, attribute_names_parsed_field, field);

    //Add the attribute names
    qdr_query_add_attribute_names(ctx->query); //this adds a list of attribute names like ["attribute1", "attribute2", "attribute3", "attribute4",]
    qd_compose_insert_string(field, results); //add a "results" key
    qd_compose_start_list(field); //start the list for results

    qdr_query_get_first(ctx->query, (*offset));

    qd_field_iterator_free(body_iter);
    qd_parse_free(body);
}
Exemplo n.º 3
0
static void qdr_agent_emit_columns(qdr_query_t *query, const char *qdr_columns[], int column_count)
{
    qd_compose_start_list(query->body);
    int i = 0;
    while (query->columns[i] >= 0) {
        assert(query->columns[i] < column_count);
        qd_compose_insert_string(query->body, qdr_columns[query->columns[i]]);
        i++;
    }
    qd_compose_end_list(query->body);
}
Exemplo n.º 4
0
static void qdr_manage_write_response_map_CT(qd_composed_field_t *body, qdr_link_t *link)
{
    qd_compose_start_map(body);

    for(int i = 0; i < QDR_LINK_COLUMN_COUNT; i++) {
        qd_compose_insert_string(body, qdr_link_columns[i]);
        qdr_agent_write_column_CT(body, i, link);
    }

    qd_compose_end_map(body);
}
Exemplo n.º 5
0
static PyObject *qd_python_send(PyObject *self, PyObject *args)
{
    qd_error_clear();
    IoAdapter           *ioa   = (IoAdapter*) self;
    qd_composed_field_t *field = 0;
    PyObject *message = 0;
    int       no_echo = 1;
    int       control = 0;

    if (!PyArg_ParseTuple(args, "O|ii", &message, &no_echo, &control))
        return 0;

    if (compose_python_message(&field, message, ioa->qd) == QD_ERROR_NONE) {
        qd_message_t *msg = qd_message();
        qd_message_compose_2(msg, field);

        qd_composed_field_t *ingress = qd_compose_subfield(0);
        qd_compose_insert_string(ingress, qd_router_id(ioa->qd));

        qd_composed_field_t *trace = qd_compose_subfield(0);
        qd_compose_start_list(trace);
        qd_compose_insert_string(trace, qd_router_id(ioa->qd));
        qd_compose_end_list(trace);

        qd_message_set_ingress_annotation(msg, ingress);
        qd_message_set_trace_annotation(msg, trace);

        PyObject *address = PyObject_GetAttrString(message, "address");
        if (address) {
            qdr_send_to2(ioa->core, msg, PyString_AsString(address), (bool) no_echo, (bool) control);
            Py_DECREF(address);
        }
        qd_compose_free(field);
        qd_message_free(msg);
        Py_RETURN_NONE;
    }
    if (!PyErr_Occurred())
        PyErr_SetString(PyExc_RuntimeError, qd_error_message());
    return 0;
}
Exemplo n.º 6
0
static void qdr_manage_write_config_auto_link_map_CT(qdr_core_t          *core,
                                                     qdr_auto_link_t     *al,
                                                     qd_composed_field_t *body,
                                                     const char          *qdr_config_auto_link_columns[])
{
    qd_compose_start_map(body);

    for(int i = 0; i < QDR_CONFIG_AUTO_LINK_COLUMN_COUNT; i++) {
        qd_compose_insert_string(body, qdr_config_auto_link_columns[i]);
        qdr_config_auto_link_insert_column_CT(al, i, body, false);
    }

    qd_compose_end_map(body);
}
Exemplo n.º 7
0
static void qdr_manage_write_address_map_CT(qdr_core_t          *core,
                                            qdr_address_t       *addr,
                                            qd_composed_field_t *body,
                                            const char          *qdr_address_columns[])
{
    qd_compose_start_map(body);

    for(int i = 0; i < QDR_ADDRESS_COLUMN_COUNT; i++) {
        qd_compose_insert_string(body, qdr_address_columns[i]);
        qdr_insert_address_columns_CT(core, addr, body, i);
    }

    qd_compose_end_map(body);
}
Exemplo n.º 8
0
void qd_message_compose_1(qd_message_t *msg, const char *to, qd_buffer_list_t *buffers)
{
    qd_composed_field_t  *field   = qd_compose(QD_PERFORMATIVE_HEADER, 0);
    qd_message_content_t *content = MSG_CONTENT(msg);

    qd_compose_start_list(field);
    qd_compose_insert_bool(field, 0);     // durable
    //qd_compose_insert_null(field);        // priority
    //qd_compose_insert_null(field);        // ttl
    //qd_compose_insert_boolean(field, 0);  // first-acquirer
    //qd_compose_insert_uint(field, 0);     // delivery-count
    qd_compose_end_list(field);

    qd_buffer_list_t out_ma;
    if (compose_message_annotations((qd_message_pvt_t*)msg, &out_ma)) {
        qd_compose_insert_buffers(field, &out_ma);
    }

    field = qd_compose(QD_PERFORMATIVE_PROPERTIES, field);
    qd_compose_start_list(field);
    qd_compose_insert_null(field);          // message-id
    qd_compose_insert_null(field);          // user-id
    qd_compose_insert_string(field, to);    // to
    //qd_compose_insert_null(field);          // subject
    //qd_compose_insert_null(field);          // reply-to
    //qd_compose_insert_null(field);          // correlation-id
    //qd_compose_insert_null(field);          // content-type
    //qd_compose_insert_null(field);          // content-encoding
    //qd_compose_insert_timestamp(field, 0);  // absolute-expiry-time
    //qd_compose_insert_timestamp(field, 0);  // creation-time
    //qd_compose_insert_null(field);          // group-id
    //qd_compose_insert_uint(field, 0);       // group-sequence
    //qd_compose_insert_null(field);          // reply-to-group-id
    qd_compose_end_list(field);

    if (buffers) {
        field = qd_compose(QD_PERFORMATIVE_BODY_DATA, field);
        qd_compose_insert_binary_buffers(field, buffers);
    }

    qd_compose_take_buffers(field, &content->buffers);
    qd_compose_free(field);
}
Exemplo n.º 9
0
static void _insert_column_CT(qdr_link_route_t *lr, int col, qd_composed_field_t *body, bool as_map)
{
    if (as_map)
        qd_compose_insert_string(body, qdr_conn_link_route_columns[col]);

    switch(col) {
    case QDR_CONN_LINK_ROUTE_NAME:
        if (lr->name)
            qd_compose_insert_string(body, lr->name);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONN_LINK_ROUTE_IDENTITY: {
        char id_str[100];
        snprintf(id_str, 100, "%"PRId64, lr->identity);
        qd_compose_insert_string(body, id_str);
        break;
    }

    case QDR_CONN_LINK_ROUTE_TYPE:
        qd_compose_insert_string(body, CONN_LINK_ROUTE_TYPE);
        break;

    case QDR_CONN_LINK_ROUTE_PATTERN:
        qd_compose_insert_string(body, lr->pattern);
        break;
    case QDR_CONN_LINK_ROUTE_DIRECTION:
        qd_compose_insert_string(body,
                                 lr->dir == QD_INCOMING
                                 ? "in"
                                 : "out");
        break;
    case QDR_CONN_LINK_ROUTE_CONTAINER_ID:
        if (lr->parent_conn && lr->parent_conn->connection_info) {
            if (lr->parent_conn->connection_info->container) {
                qd_compose_insert_string(body,
                                         lr->parent_conn->connection_info->container);
                break;
            }
        }
        qd_compose_insert_null(body);
        break;
    }
}
Exemplo n.º 10
0
static void qdr_config_auto_link_insert_column_CT(qdr_auto_link_t *al, int col, qd_composed_field_t *body, bool as_map)
{
    const char *text = 0;
    const char *key;
    char id_str[100];

    if (as_map)
        qd_compose_insert_string(body, qdr_config_auto_link_columns[col]);

    switch(col) {
    case QDR_CONFIG_AUTO_LINK_NAME:
        if (al->name)
            qd_compose_insert_string(body, al->name);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_IDENTITY:
        snprintf(id_str, 100, "%"PRId64, al->identity);
        qd_compose_insert_string(body, id_str);
        break;

    case QDR_CONFIG_AUTO_LINK_TYPE:
        qd_compose_insert_string(body, CONFIG_AUTOLINK_TYPE);
        break;

    case QDR_CONFIG_AUTO_LINK_ADDR:
        key = (const char*) qd_hash_key_by_handle(al->addr->hash_handle);
        if (key && key[0] == 'M')
            qd_compose_insert_string(body, &key[2]);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_DIR:
        text = al->dir == QD_INCOMING ? "in" : "out";
        qd_compose_insert_string(body, text);
        break;

    case QDR_CONFIG_AUTO_LINK_PHASE:
        qd_compose_insert_int(body, al->phase);
        break;

    case QDR_CONFIG_AUTO_LINK_CONNECTION:
    case QDR_CONFIG_AUTO_LINK_CONTAINER_ID:
        if (al->conn_id) {
            key = (const char*) qd_hash_key_by_handle(al->conn_id->hash_handle);
            if (key && key[0] == 'L' && col == QDR_CONFIG_AUTO_LINK_CONNECTION) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
            if (key && key[0] == 'C' && col == QDR_CONFIG_AUTO_LINK_CONTAINER_ID) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
        }
        qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_LINK_REF:
        if (al->link) {
            snprintf(id_str, 100, "%"PRId64, al->link->identity);
            qd_compose_insert_string(body, id_str);
        } else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_OPER_STATUS:
        switch (al->state) {
        case QDR_AUTO_LINK_STATE_INACTIVE:  text = "inactive";  break;
        case QDR_AUTO_LINK_STATE_ATTACHING: text = "attaching"; break;
        case QDR_AUTO_LINK_STATE_FAILED:    text = "failed";    break;
        case QDR_AUTO_LINK_STATE_ACTIVE:    text = "active";    break;
        case QDR_AUTO_LINK_STATE_QUIESCING: text = "quiescing"; break;
        case QDR_AUTO_LINK_STATE_IDLE:      text = "idle";      break;
        }

        if (text)
            qd_compose_insert_string(body, text);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_AUTO_LINK_LAST_ERROR:
        if (al->last_error)
            qd_compose_insert_string(body, al->last_error);
        else
            qd_compose_insert_null(body);
        break;
    }
}
Exemplo n.º 11
0
static void qdr_agent_write_column_CT(qd_composed_field_t *body, int col, qdr_core_t *core)
{

    switch(col) {
    case QDR_ROUTER_IDENTITY:
        // There is only one instance of router. Just give it an identity of 1
        qd_compose_insert_string(body, "1");
        break;
    case QDR_ROUTER_TYPE:
        qd_compose_insert_string(body, "org.apache.qpid.dispatch.router");
        break;

    case QDR_ROUTER_MODE:
        qd_compose_insert_string(body, router_mode(core->router_mode));
        break;

    case QDR_ROUTER_AREA:
        if (core->router_area)
            qd_compose_insert_string(body, core->router_area);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_ROUTER_VERSION:
        qd_compose_insert_string(body, QPID_DISPATCH_VERSION);
        break;

    case QDR_ROUTER_HELLO_INTERVAL:
        qd_compose_insert_null(body);
        break;

    case QDR_ROUTER_ADDR_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(core->addrs));
        break;

    case QDR_ROUTER_LINK_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(core->open_links));
        break;

    case QDR_ROUTER_NODE_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(core->routers));
        break;

    case QDR_ROUTER_CONNECTION_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(core->open_connections));
        break;

    case QDR_ROUTER_LINK_ROUTE_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(core->link_routes));
        break;

    case QDR_ROUTER_AUTO_LINK_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(core->auto_links));
        break;

    case QDR_ROUTER_ROUTER_ID:
    case QDR_ROUTER_ID:
    case QDR_ROUTER_NAME:
        if (core->router_id)
            qd_compose_insert_string(body, core->router_id);
        else
            qd_compose_insert_null(body);
        break;

    default:
        qd_compose_insert_null(body);
        break;
    }
}
Exemplo n.º 12
0
static char *test_tracemask(void *context)
{
    qd_bitmask_t    *bm = NULL;
    qd_tracemask_t  *tm = qd_tracemask();
    qd_buffer_list_t list;
    static char      error[1024];

    error[0] = 0;
    qd_iterator_set_address(false, "0", "ROUTER");

    qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.A", 0);
    qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.B", 1);
    qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.C", 2);
    qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.D", 3);
    qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.E", 4);
    qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.F", 5);

    qd_tracemask_set_link(tm, 0, 4);
    qd_tracemask_set_link(tm, 3, 10);
    qd_tracemask_set_link(tm, 4, 3);
    qd_tracemask_set_link(tm, 5, 2);

    qd_composed_field_t *comp = qd_compose_subfield(0);
    qd_compose_start_list(comp);
    qd_compose_insert_string(comp, "0/Router.A");
    qd_compose_insert_string(comp, "0/Router.D");
    qd_compose_insert_string(comp, "0/Router.E");
    qd_compose_end_list(comp);

    DEQ_INIT(list);
    qd_compose_take_buffers(comp, &list);
    qd_compose_free(comp);

    int length = 0;
    qd_buffer_t *buf = DEQ_HEAD(list);
    while (buf) {
        length += qd_buffer_size(buf);
        buf = DEQ_NEXT(buf);
    }

    qd_iterator_t     *iter = qd_iterator_buffer(DEQ_HEAD(list), 0, length, ITER_VIEW_ALL);
    qd_parsed_field_t *pf   = qd_parse(iter);
    qd_iterator_free(iter);

    int ingress = -1;

    bm = qd_tracemask_create(tm, pf, &ingress);
    if (qd_bitmask_cardinality(bm) != 3) {
        sprintf(error, "Expected cardinality of 3, got %d", qd_bitmask_cardinality(bm));
        goto cleanup;
    }
    if (ingress != 0) {
        sprintf(error, "(A) Expected ingress index of 0, got %d", ingress);
        goto cleanup;
    }
    int total = 0;
    int bit, c;
    for (QD_BITMASK_EACH(bm, bit, c)) {
        total += bit;
    }
    if (total != 17) {
        sprintf(error, "Expected total bit value of 17, got %d", total);
        goto cleanup;
    }

    qd_bitmask_free(bm);
    bm = 0;
    qd_tracemask_del_router(tm, 3);
    qd_tracemask_remove_link(tm, 0);

    ingress = -1;
    bm = qd_tracemask_create(tm, pf, &ingress);
    qd_parse_free(pf);
    pf = 0;
    if (qd_bitmask_cardinality(bm) != 1) {
        sprintf(error, "Expected cardinality of 1, got %d", qd_bitmask_cardinality(bm));
        goto cleanup;
    }
    if (ingress != 0) {
        sprintf(error, "(B) Expected ingress index of 0, got %d", ingress);
        goto cleanup;
    }

    total = 0;
    for (QD_BITMASK_EACH(bm, bit, c)) {
        total += bit;
    }
    if (total != 3) {
        sprintf(error, "Expected total bit value of 3, got %d", total);
        // fallthrough
    }

cleanup:
    qd_parse_free(pf);
    qd_tracemask_free(tm);
    qd_bitmask_free(bm);
    for (qd_buffer_t *buf = DEQ_HEAD(list); buf; buf = DEQ_HEAD(list)) {
        DEQ_REMOVE_HEAD(list);
        qd_buffer_free(buf);
    }
    return *error ? error : 0;
}
static void qdr_config_link_route_insert_column_CT(qdr_link_route_t *lr, int col, qd_composed_field_t *body, bool as_map)
{
    const char *text = 0;
    const char *key;

    if (as_map)
        qd_compose_insert_string(body, qdr_config_link_route_columns[col]);

    switch(col) {
    case QDR_CONFIG_LINK_ROUTE_NAME:
        if (lr->name)
            qd_compose_insert_string(body, lr->name);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_LINK_ROUTE_IDENTITY: {
        char id_str[100];
        snprintf(id_str, 100, "%"PRId64, lr->identity);
        qd_compose_insert_string(body, id_str);
        break;
    }

    case QDR_CONFIG_LINK_ROUTE_TYPE:
        qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.config.linkRoute");
        break;

    case QDR_CONFIG_LINK_ROUTE_PREFIX:
        key = (const char*) qd_hash_key_by_handle(lr->addr->hash_handle);
        if (key && (key[0] == 'C' || key[0] == 'D'))
            qd_compose_insert_string(body, &key[1]);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_LINK_ROUTE_DISTRIBUTION:
        switch (lr->treatment) {
        case QD_TREATMENT_LINK_BALANCED: text = "linkBalanced"; break;
        default:
            text = 0;
        }

        if (text)
            qd_compose_insert_string(body, text);
        else
            qd_compose_insert_null(body);

        break;

    case QDR_CONFIG_LINK_ROUTE_CONNECTION:
    case QDR_CONFIG_LINK_ROUTE_CONTAINER_ID:
        if (lr->conn_id) {
            key = (const char*) qd_hash_key_by_handle(lr->conn_id->hash_handle);
            if (key && key[0] == 'L' && col == QDR_CONFIG_LINK_ROUTE_CONNECTION) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
            if (key && key[0] == 'C' && col == QDR_CONFIG_LINK_ROUTE_CONTAINER_ID) {
                qd_compose_insert_string(body, &key[1]);
                break;
            }
        }
        qd_compose_insert_null(body);
        break;

    case QDR_CONFIG_LINK_ROUTE_DIR:
        text = lr->dir == QD_INCOMING ? "in" : "out";
        qd_compose_insert_string(body, text);
        break;

    case QDR_CONFIG_LINK_ROUTE_OPER_STATUS:
        text = lr->active ? "active" : "inactive";
        qd_compose_insert_string(body, text);
        break;
    }
}
Exemplo n.º 14
0
static qd_iterator_t *router_annotate_message(qd_router_t       *router,
                                              qd_parsed_field_t *in_ma,
                                              qd_message_t      *msg,
                                              qd_bitmask_t     **link_exclusions,
                                              bool               strip_inbound_annotations)
{
    qd_iterator_t *ingress_iter = 0;

    qd_parsed_field_t *trace   = 0;
    qd_parsed_field_t *ingress = 0;
    qd_parsed_field_t *to      = 0;
    qd_parsed_field_t *phase   = 0;

    *link_exclusions = 0;

    if (in_ma && !strip_inbound_annotations) {
        uint32_t count = qd_parse_sub_count(in_ma);
        bool done = false;

        for (uint32_t idx = 0; idx < count && !done; idx++) {
            qd_parsed_field_t *sub  = qd_parse_sub_key(in_ma, idx);
            if (!sub)
                continue;
            qd_iterator_t *iter = qd_parse_raw(sub);
            if (!iter)
                continue;

            if        (qd_iterator_equal(iter, (unsigned char*) QD_MA_TRACE)) {
                trace = qd_parse_sub_value(in_ma, idx);
            } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_INGRESS)) {
                ingress = qd_parse_sub_value(in_ma, idx);
            } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_TO)) {
                to = qd_parse_sub_value(in_ma, idx);
            } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_PHASE)) {
                phase = qd_parse_sub_value(in_ma, idx);
            }
            done = trace && ingress && to && phase;
        }
    }

    //
    // QD_MA_TRACE:
    // If there is a trace field, append this router's ID to the trace.
    // If the router ID is already in the trace the msg has looped.
    //
    qd_composed_field_t *trace_field = qd_compose_subfield(0);
    qd_compose_start_list(trace_field);
    if (trace) {
        if (qd_parse_is_list(trace)) {
            //
            // Create a link-exclusion map for the items in the trace.  This map will
            // contain a one-bit for each link that leads to a neighbor router that
            // the message has already passed through.
            //
            *link_exclusions = qd_tracemask_create(router->tracemask, trace);

            //
            // Append this router's ID to the trace.
            //
            uint32_t idx = 0;
            qd_parsed_field_t *trace_item = qd_parse_sub_value(trace, idx);
            while (trace_item) {
                qd_iterator_t *iter = qd_parse_raw(trace_item);
                qd_iterator_reset_view(iter, ITER_VIEW_ALL);
                qd_compose_insert_string_iterator(trace_field, iter);
                idx++;
                trace_item = qd_parse_sub_value(trace, idx);
            }
        }
    }

    qd_compose_insert_string(trace_field, node_id);
    qd_compose_end_list(trace_field);
    qd_message_set_trace_annotation(msg, trace_field);

    //
    // QD_MA_TO:
    // Preserve the existing value.
    //
    if (to) {
        qd_composed_field_t *to_field = qd_compose_subfield(0);
        qd_compose_insert_string_iterator(to_field, qd_parse_raw(to));
        qd_message_set_to_override_annotation(msg, to_field);
    }

    //
    // QD_MA_PHASE:
    // Preserve the existing value.
    //
    if (phase) {
        int phase_val = qd_parse_as_int(phase);
        qd_message_set_phase_annotation(msg, phase_val);
    }

    //
    // QD_MA_INGRESS:
    // If there is no ingress field, annotate the ingress as
    // this router else keep the original field.
    //
    qd_composed_field_t *ingress_field = qd_compose_subfield(0);
    if (ingress && qd_parse_is_scalar(ingress)) {
        ingress_iter = qd_parse_raw(ingress);
        qd_compose_insert_string_iterator(ingress_field, ingress_iter);
    } else
        qd_compose_insert_string(ingress_field, node_id);
    qd_message_set_ingress_annotation(msg, ingress_field);

    //
    // Return the iterator to the ingress field _if_ it was present.
    // If we added the ingress, return NULL.
    //
    return ingress_iter;
}
Exemplo n.º 15
0
/**
 * Inbound Delivery Handler
 */
static void AMQP_rx_handler(void* context, qd_link_t *link, pn_delivery_t *pnd)
{
    qd_router_t    *router   = (qd_router_t*) context;
    pn_link_t      *pn_link  = qd_link_pn(link);
    qdr_link_t     *rlink    = (qdr_link_t*) qd_link_get_context(link);
    qdr_delivery_t *delivery = 0;
    qd_message_t   *msg;

    //
    // Receive the message into a local representation.  If the returned message
    // pointer is NULL, we have not yet received a complete message.
    //
    // Note:  In the link-routing case, consider cutting the message through.  There's
    //        no reason to wait for the whole message to be received before starting to
    //        send it.
    //
    msg = qd_message_receive(pnd);
    if (!msg)
        return;

    //
    // Consume the delivery.
    //
    pn_link_advance(pn_link);

    //
    // If there's no router link, free the message and finish.  It's likely that the link
    // is closing.
    //
    if (!rlink) {
        qd_message_free(msg);
        return;
    }

    //
    // Handle the link-routed case
    //
    if (qdr_link_is_routed(rlink)) {
        pn_delivery_tag_t dtag = pn_delivery_tag(pnd);
        delivery = qdr_link_deliver_to_routed_link(rlink, msg, pn_delivery_settled(pnd), (uint8_t*) dtag.start, dtag.size);
        if (delivery) {
            if (pn_delivery_settled(pnd))
                pn_delivery_settle(pnd);
            else {
                pn_delivery_set_context(pnd, delivery);
                qdr_delivery_set_context(delivery, pnd);
                qdr_delivery_incref(delivery);
            }
        }
        return;
    }

    //
    // Determine if the incoming link is anonymous.  If the link is addressed,
    // there are some optimizations we can take advantage of.
    //
    bool anonymous_link = qdr_link_is_anonymous(rlink);

    //
    // Determine if the user of this connection is allowed to proxy the
    // user_id of messages. A message user_id is proxied when the
    // property value differs from the authenticated user name of the connection.
    // If the user is not allowed to proxy the user_id then the message user_id
    // must be blank or it must be equal to the connection user name.
    //
    bool             check_user = false;
    qd_connection_t *conn       = qd_link_connection(link);
    if (conn->policy_settings) 
        check_user = !conn->policy_settings->allowUserIdProxy;

    //
    // Validate the content of the delivery as an AMQP message.  This is done partially, only
    // to validate that we can find the fields we need to route the message.
    //
    // If the link is anonymous, we must validate through the message properties to find the
    // 'to' field.  If the link is not anonymous, we don't need the 'to' field as we will be
    // using the address from the link target.
    //
    qd_message_depth_t  validation_depth = (anonymous_link || check_user) ? QD_DEPTH_PROPERTIES : QD_DEPTH_MESSAGE_ANNOTATIONS;
    bool                valid_message    = qd_message_check(msg, validation_depth);

    if (valid_message) {
        if (check_user) {
            // This connection must not allow proxied user_id
            qd_iterator_t *userid_iter  = qd_message_field_iterator(msg, QD_FIELD_USER_ID);
            if (userid_iter) {
                // The user_id property has been specified
                if (qd_iterator_remaining(userid_iter) > 0) {
                    // user_id property in message is not blank
                    if (!qd_iterator_equal(userid_iter, (const unsigned char *)conn->user_id)) {
                        // This message is rejected: attempted user proxy is disallowed
                        qd_log(router->log_source, QD_LOG_DEBUG, "Message rejected due to user_id proxy violation. User:%s", conn->user_id);
                        pn_link_flow(pn_link, 1);
                        pn_delivery_update(pnd, PN_REJECTED);
                        pn_delivery_settle(pnd);
                        qd_message_free(msg);
                        qd_iterator_free(userid_iter);
                        return;
                    }
                }
                qd_iterator_free(userid_iter);
            }
        }

        qd_parsed_field_t   *in_ma        = qd_message_message_annotations(msg);
        qd_bitmask_t        *link_exclusions;
        bool                 strip        = qdr_link_strip_annotations_in(rlink);
        qd_iterator_t *ingress_iter = router_annotate_message(router, in_ma, msg, &link_exclusions, strip);

        if (anonymous_link) {
            qd_iterator_t *addr_iter = 0;
            int phase = 0;
            
            //
            // If the message has delivery annotations, get the to-override field from the annotations.
            //
            if (in_ma) {
                qd_parsed_field_t *ma_to = qd_parse_value_by_key(in_ma, QD_MA_TO);
                if (ma_to) {
                    addr_iter = qd_iterator_dup(qd_parse_raw(ma_to));
                    phase = qd_message_get_phase_annotation(msg);
                }
            }

            //
            // Still no destination address?  Use the TO field from the message properties.
            //
            if (!addr_iter)
                addr_iter = qd_message_field_iterator(msg, QD_FIELD_TO);

            if (addr_iter) {
                qd_iterator_reset_view(addr_iter, ITER_VIEW_ADDRESS_HASH);
                if (phase > 0)
                    qd_iterator_annotate_phase(addr_iter, '0' + (char) phase);
                delivery = qdr_link_deliver_to(rlink, msg, ingress_iter, addr_iter, pn_delivery_settled(pnd),
                                               link_exclusions);
            }
        } else {
            const char *term_addr = pn_terminus_get_address(qd_link_remote_target(link));
            if (!term_addr)
                term_addr = pn_terminus_get_address(qd_link_source(link));

            if (term_addr) {
                qd_composed_field_t *to_override = qd_compose_subfield(0);
                qd_compose_insert_string(to_override, term_addr);
                qd_message_set_to_override_annotation(msg, to_override);
                int phase = qdr_link_phase(rlink);
                if (phase != 0)
                    qd_message_set_phase_annotation(msg, phase);
            }
            delivery = qdr_link_deliver(rlink, msg, ingress_iter, pn_delivery_settled(pnd), link_exclusions);
        }

        if (delivery) {
            if (pn_delivery_settled(pnd))
                pn_delivery_settle(pnd);
            else {
                pn_delivery_set_context(pnd, delivery);
                qdr_delivery_set_context(delivery, pnd);
                qdr_delivery_incref(delivery);
            }
        } else {
            //
            // The message is now and will always be unroutable because there is no address.
            //
            pn_link_flow(pn_link, 1);
            pn_delivery_update(pnd, PN_REJECTED);
            pn_delivery_settle(pnd);
            qd_message_free(msg);
        }

        //
        // Rules for delivering messages:
        //
        // For addressed (non-anonymous) links:
        //   to-override must be set (done in the core?)
        //   uses qdr_link_deliver to hand over to the core
        //
        // For anonymous links:
        //   If there's a to-override in the annotations, use that address
        //   Or, use the 'to' field in the message properties
        //



    } else {
        //
        // Message is invalid.  Reject the message and don't involve the router core.
        //
        pn_link_flow(pn_link, 1);
        pn_delivery_update(pnd, PN_REJECTED);
        pn_delivery_settle(pnd);
        qd_message_free(msg);
    }
}
Exemplo n.º 16
0
static void qdr_insert_address_columns_CT(qdr_core_t          *core,
                                          qdr_address_t       *addr,
                                          qd_composed_field_t *body,
                                          int                  column_index)
{
    switch(column_index) {
    case QDR_ADDRESS_NAME:
    case QDR_ADDRESS_IDENTITY:
    case QDR_ADDRESS_KEY:
        if (addr->hash_handle)
            qd_compose_insert_string(body, (const char*) qd_hash_key_by_handle(addr->hash_handle));
        else
            qd_compose_insert_null(body);
        break;

    case QDR_ADDRESS_TYPE:
        qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.address");
        break;

    case QDR_ADDRESS_DISTRIBUTION: {
        switch (addr->treatment) {
        case QD_TREATMENT_MULTICAST_FLOOD:  qd_compose_insert_string(body, "flood");        break;
        case QD_TREATMENT_MULTICAST_ONCE:   qd_compose_insert_string(body, "multicast");    break;
        case QD_TREATMENT_ANYCAST_CLOSEST:  qd_compose_insert_string(body, "closest");      break;
        case QD_TREATMENT_ANYCAST_BALANCED: qd_compose_insert_string(body, "balanced");     break;
        case QD_TREATMENT_LINK_BALANCED:    qd_compose_insert_string(body, "linkBalanced"); break;
        }
        break;
    }

    case QDR_ADDRESS_IN_PROCESS:
        qd_compose_insert_uint(body, DEQ_SIZE(addr->subscriptions));
        break;

    case QDR_ADDRESS_SUBSCRIBER_COUNT:
        qd_compose_insert_uint(body, DEQ_SIZE(addr->rlinks));
        break;

    case QDR_ADDRESS_REMOTE_COUNT:
        qd_compose_insert_uint(body, qd_bitmask_cardinality(addr->rnodes));
        break;

    case QDR_ADDRESS_CONTAINER_COUNT:
        qd_compose_insert_uint(body, DEQ_SIZE(addr->conns));
        break;

    case QDR_ADDRESS_REMOTE_HOST_ROUTERS: {
        qd_compose_start_list(body);
        int c;
        int bit;
        for (QD_BITMASK_EACH(addr->rnodes, bit, c)) {
            qdr_node_t *rnode = core->routers_by_mask_bit[bit];
            if (rnode && rnode->owning_addr) {
                const char *ar = (char*) qd_hash_key_by_handle(rnode->owning_addr->hash_handle);
                qd_compose_insert_string(body, ar + 1); // Remove the 'R' prefix from the router address
            }
        }
        qd_compose_end_list(body);
        break;
    }

    case QDR_ADDRESS_DELIVERIES_INGRESS:
        qd_compose_insert_ulong(body, addr->deliveries_ingress);
        break;

    case QDR_ADDRESS_DELIVERIES_EGRESS:
        qd_compose_insert_ulong(body, addr->deliveries_egress);
        break;

    case QDR_ADDRESS_DELIVERIES_TRANSIT:
        qd_compose_insert_ulong(body, addr->deliveries_transit);
        break;

    case QDR_ADDRESS_DELIVERIES_TO_CONTAINER:
        qd_compose_insert_ulong(body, addr->deliveries_to_container);
        break;

    case QDR_ADDRESS_DELIVERIES_FROM_CONTAINER:
        qd_compose_insert_ulong(body, addr->deliveries_from_container);
        break;

    case QDR_ADDRESS_TRANSIT_OUTSTANDING:
        if (addr->outstanding_deliveries) {
            qd_compose_start_list(body);
            for (int i = 0; i < qd_bitmask_width(); i++)
                qd_compose_insert_long(body, addr->outstanding_deliveries[i]);
            qd_compose_end_list(body);
        } else
            qd_compose_insert_null(body);
        break;

    case QDR_ADDRESS_TRACKED_DELIVERIES:
        qd_compose_insert_long(body, addr->tracked_deliveries);
        break;

    default:
        qd_compose_insert_null(body);
        break;
    }

}
Exemplo n.º 17
0
static void qdr_agent_write_column_CT(qd_composed_field_t *body, int col, qdr_link_t *link)
{
    char *text = 0;

    switch(col) {
    case QDR_LINK_NAME: {
        if (link->name)
            qd_compose_insert_string(body, link->name);
        else
            qd_compose_insert_null(body);
        break;
    }

    case QDR_LINK_IDENTITY: {
        char id[100];
        snprintf(id, 100, "%"PRId64, link->identity);
        qd_compose_insert_string(body, id);
        break;
    }

    case QDR_LINK_TYPE:
        qd_compose_insert_string(body, "org.apache.qpid.dispatch.router.link");
        break;

    case QDR_LINK_LINK_NAME:
        qd_compose_insert_string(body, link->name);
        break;

    case QDR_LINK_LINK_TYPE:
        qd_compose_insert_string(body, qd_link_type_name(link->link_type));
        break;

    case QDR_LINK_LINK_DIR:
        qd_compose_insert_string(body, link->link_direction == QD_INCOMING ? "in" : "out");
        break;

    case QDR_LINK_OWNING_ADDR:
        if (link->owning_addr)
            qd_compose_insert_string(body, address_key(link->owning_addr));
        else
            qd_compose_insert_null(body);
        break;

    case QDR_LINK_CAPACITY:
        qd_compose_insert_uint(body, link->capacity);
        break;

    case QDR_LINK_PEER:
        if (link->connected_link) {
            char id[100];
            snprintf(id, 100, "%"PRId64, link->connected_link->identity);
            qd_compose_insert_string(body, id);
        } else
            qd_compose_insert_null(body);
        break;

    case QDR_LINK_UNDELIVERED_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(link->undelivered));
        break;

    case QDR_LINK_UNSETTLED_COUNT:
        qd_compose_insert_ulong(body, DEQ_SIZE(link->unsettled));
        break;

    case QDR_LINK_DELIVERY_COUNT:
        qd_compose_insert_ulong(body, link->total_deliveries);
        break;

    case QDR_LINK_CONNECTION_ID:
        qd_compose_insert_ulong(body, link->conn->management_id);
        break;

    case QDR_LINK_ADMIN_STATE:
        text = link->admin_enabled ? "enabled" : "disabled";
        qd_compose_insert_string(body, text);
        break;

    case QDR_LINK_OPER_STATE:
        switch (link->oper_status) {
        case QDR_LINK_OPER_UP:        text = "up";        break;
        case QDR_LINK_OPER_DOWN:      text = "down";      break;
        case QDR_LINK_OPER_QUIESCING: text = "quiescing"; break;
        case QDR_LINK_OPER_IDLE:      text = "idle";      break;
        default:
            text = 0;
        }
        if (!!text)
            qd_compose_insert_string(body, text);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_LINK_PRESETTLED_COUNT:
        qd_compose_insert_ulong(body, link->presettled_deliveries);
        break;

    case QDR_LINK_ACCEPTED_COUNT:
        qd_compose_insert_ulong(body, link->accepted_deliveries);
        break;

    case QDR_LINK_REJECTED_COUNT:
        qd_compose_insert_ulong(body, link->rejected_deliveries);
        break;

    case QDR_LINK_RELEASED_COUNT:
        qd_compose_insert_ulong(body, link->released_deliveries);
        break;

    case QDR_LINK_MODIFIED_COUNT:
        qd_compose_insert_ulong(body, link->modified_deliveries);
        break;

    default:
        qd_compose_insert_null(body);
        break;
    }
}
Exemplo n.º 18
0
qd_error_t qd_py_to_composed(PyObject *value, qd_composed_field_t *field)
{
    qd_python_check_lock();
    qd_error_clear();
    if (value == Py_None) {
        qd_compose_insert_null(field);
    }
    else if (PyBool_Check(value)) {
        qd_compose_insert_bool(field, PyInt_AS_LONG(value) ? 1 : 0);
    }
    else if (PyInt_Check(value)) {
        qd_compose_insert_long(field, (int64_t) PyInt_AS_LONG(value));
    }
    else if (PyLong_Check(value)) {
        qd_compose_insert_long(field, (int64_t) PyLong_AsLongLong(value));
    }
    else if (PyString_Check(value) || PyUnicode_Check(value)) {
        qd_compose_insert_string(field, PyString_AsString(value));
    }
    else if (PyDict_Check(value)) {
        Py_ssize_t  iter = 0;
        PyObject   *key;
        PyObject   *val;
        qd_compose_start_map(field);
        while (PyDict_Next(value, &iter, &key, &val)) {
            qd_py_to_composed(key, field); QD_ERROR_RET();
            qd_py_to_composed(val, field); QD_ERROR_RET();
        }
        QD_ERROR_PY_RET();
        qd_compose_end_map(field);
    }

    else if (PyList_Check(value)) {
        Py_ssize_t count = PyList_Size(value);
        if (count == 0)
            qd_compose_empty_list(field);
        else {
            qd_compose_start_list(field);
            for (Py_ssize_t idx = 0; idx < count; idx++) {
                PyObject *item = PyList_GetItem(value, idx); QD_ERROR_PY_RET();
                qd_py_to_composed(item, field); QD_ERROR_RET();
            }
            qd_compose_end_list(field);
        }
    }

    else if (PyTuple_Check(value)) {
        Py_ssize_t count = PyTuple_Size(value);
        if (count == 0)
            qd_compose_empty_list(field);
        else {
            qd_compose_start_list(field);
            for (Py_ssize_t idx = 0; idx < count; idx++) {
                PyObject *item = PyTuple_GetItem(value, idx); QD_ERROR_PY_RET();
                qd_py_to_composed(item, field); QD_ERROR_RET();
            }
            qd_compose_end_list(field);
        }
    }
    else {
        PyObject *type=0, *typestr=0, *repr=0;
        if ((type = PyObject_Type(value)) &&
            (typestr = PyObject_Str(type)) &&
            (repr = PyObject_Repr(value)))
            qd_error(QD_ERROR_TYPE, "Can't compose object of type %s: %s",
                     PyString_AsString(typestr), PyString_AsString(repr));
        else
            qd_error(QD_ERROR_TYPE, "Can't compose python object of unknown type");

        Py_XDECREF(type);
        Py_XDECREF(typestr);
        Py_XDECREF(repr);
    }
    return qd_error_code();
}