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); }
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); }
static void qdr_agent_write_link_CT(qdr_query_t *query, qdr_link_t *link) { qd_composed_field_t *body = query->body; qd_compose_start_list(body); int i = 0; while (query->columns[i] >= 0) { qdr_agent_write_column_CT(body, query->columns[i], link); i++; } qd_compose_end_list(body); }
static void qdr_agent_write_config_auto_link_CT(qdr_query_t *query, qdr_auto_link_t *al) { qd_composed_field_t *body = query->body; qd_compose_start_list(body); int i = 0; while (query->columns[i] >= 0) { qdr_config_auto_link_insert_column_CT(al, query->columns[i], body, false); i++; } qd_compose_end_list(body); }
static void _write_as_list_CT(qdr_query_t *query, qdr_link_route_t *lr) { qd_composed_field_t *body = query->body; qd_compose_start_list(body); int i = 0; while (query->columns[i] >= 0) { _insert_column_CT(lr, query->columns[i], body, false); i++; } qd_compose_end_list(body); }
static void qd_manage_response_handler(void *context, const qd_amqp_error_t *status, bool more) { qd_management_context_t *ctx = (qd_management_context_t*) context; if (ctx->operation_type == QD_ROUTER_OPERATION_QUERY) { if (status->status / 100 == 2) { // There is no error, proceed to conditionally call get_next if (more) { ctx->current_count++; // Increment how many you have at hand if (ctx->count != ctx->current_count) { qdr_query_get_next(ctx->query); return; } else // // This is the one case where the core agent won't free the query itself. // qdr_query_free(ctx->query); } } qd_compose_end_list(ctx->field); qd_compose_end_map(ctx->field); } else if (ctx->operation_type == QD_ROUTER_OPERATION_DELETE) { // The body of the delete response message MUST consist of an amqp-value section containing a Map with zero entries. qd_compose_start_map(ctx->field); qd_compose_end_map(ctx->field); } qd_field_iterator_t *reply_to = 0; qd_composed_field_t *fld = 0; // Start composing the message. // First set the properties on the message like reply_to, correlation-id etc. qd_set_properties(ctx->source, &reply_to, &fld); // Second, set the status on the message, QD_AMQP_OK or QD_AMQP_BAD_REQUEST and so on. qd_set_response_status(status, &fld); // Finally, compose and send the message. qd_message_compose_3(ctx->msg, fld, ctx->field); qdr_send_to1(ctx->core, ctx->msg, reply_to, true, false); // We have come to the very end. Free the appropriate memory. // Just go over this with Ted to see if I freed everything. qd_field_iterator_free(reply_to); qd_compose_free(fld); qd_message_free(ctx->msg); qd_message_free(ctx->source); qd_compose_free(ctx->field); free_qd_management_context_t(ctx); }
static void qdr_manage_write_address_list_CT(qdr_core_t *core, qdr_query_t *query, qdr_address_t *addr) { qd_composed_field_t *body = query->body; qd_compose_start_list(body); if (!addr) return; int i = 0; while (query->columns[i] >= 0) { qdr_insert_address_columns_CT(core, addr, body, query->columns[i]); i++; } qd_compose_end_list(body); }
static void qd_set_properties(qd_message_t *msg, qd_field_iterator_t **reply_to, qd_composed_field_t **fld) { qd_field_iterator_t *correlation_id = qd_message_field_iterator_typed(msg, QD_FIELD_CORRELATION_ID); // Grab the reply_to field from the incoming message. This is the address we will send the response to. *reply_to = qd_message_field_iterator(msg, QD_FIELD_REPLY_TO); *fld = qd_compose(QD_PERFORMATIVE_PROPERTIES, 0); qd_compose_start_list(*fld); qd_compose_insert_null(*fld); // message-id qd_compose_insert_null(*fld); // user-id qd_compose_insert_string_iterator(*fld, *reply_to); // to qd_compose_insert_null(*fld); // subject qd_compose_insert_null(*fld); qd_compose_insert_typed_iterator(*fld, correlation_id); qd_compose_end_list(*fld); qd_field_iterator_free(correlation_id); }
static qd_error_t compose_python_message(qd_composed_field_t **field, PyObject *message, qd_dispatch_t* qd) { *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_py_attr_to_composed(message, "address", *field); QD_ERROR_RET(); // to qd_compose_insert_null(*field); // subject qd_compose_insert_null(*field); // reply-to qd_py_attr_to_composed(message, "correlation_id", *field); QD_ERROR_RET(); // correlation-id qd_compose_end_list(*field); *field = qd_compose(QD_PERFORMATIVE_APPLICATION_PROPERTIES, *field); QD_ERROR_RET(); qd_py_attr_to_composed(message, "properties", *field); QD_ERROR_RET(); *field = qd_compose(QD_PERFORMATIVE_BODY_AMQP_VALUE, *field); QD_ERROR_RET(); qd_py_attr_to_composed(message, "body", *field); QD_ERROR_RET(); return qd_error_code(); }
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; }
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_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; } }
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; }
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(); }