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); }
// create a buffer chain holding the outgoing message annotations section static bool compose_message_annotations(qd_message_pvt_t *msg, qd_buffer_list_t *out) { if (!DEQ_IS_EMPTY(msg->ma_to_override) || !DEQ_IS_EMPTY(msg->ma_trace) || !DEQ_IS_EMPTY(msg->ma_ingress)) { qd_composed_field_t *out_ma = qd_compose(QD_PERFORMATIVE_MESSAGE_ANNOTATIONS, 0); qd_compose_start_map(out_ma); if (!DEQ_IS_EMPTY(msg->ma_to_override)) { qd_compose_insert_symbol(out_ma, QD_MA_TO); qd_compose_insert_buffers(out_ma, &msg->ma_to_override); } if (!DEQ_IS_EMPTY(msg->ma_trace)) { qd_compose_insert_symbol(out_ma, QD_MA_TRACE); qd_compose_insert_buffers(out_ma, &msg->ma_trace); } if (!DEQ_IS_EMPTY(msg->ma_ingress)) { qd_compose_insert_symbol(out_ma, QD_MA_INGRESS); qd_compose_insert_buffers(out_ma, &msg->ma_ingress); } qd_compose_end_map(out_ma); qd_compose_take_buffers(out_ma, out); qd_compose_free(out_ma); return true; } return false; }
static void _write_as_map_CT(qdr_query_t *query, qdr_link_route_t *lr) { qd_composed_field_t *body = query->body; qd_compose_start_map(body); for (int col = 0; col < QDR_CONN_LINK_ROUTE_COLUMN_COUNT; col++) _insert_column_CT(lr, col, body, true); qd_compose_end_map(body); }
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); }
static void qdra_link_update_set_status(qdr_core_t *core, qdr_query_t *query, qdr_link_t *link) { if (link) { //link->admin_state = qd_field_iterator_copy(adm_state); qdr_manage_write_response_map_CT(query->body, link); query->status = QD_AMQP_OK; } else { query->status = QD_AMQP_NOT_FOUND; qd_compose_start_map(query->body); qd_compose_end_map(query->body); } }
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); }
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); }
/** * 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); }
static void qdra_link_set_bad_request(qdr_query_t *query) { query->status = QD_AMQP_BAD_REQUEST; qd_compose_start_map(query->body); qd_compose_end_map(query->body); }
void qdra_config_auto_link_create_CT(qdr_core_t *core, qd_field_iterator_t *name, qdr_query_t *query, qd_parsed_field_t *in_body) { while (true) { // // Ensure there isn't a duplicate name and that the body is a map // qdr_auto_link_t *al = DEQ_HEAD(core->auto_links); while (al) { if (name && al->name && qd_field_iterator_equal(name, (const unsigned char*) al->name)) break; al = DEQ_NEXT(al); } if (!!al) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = "Name conflicts with an existing entity"; qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_AUTOLINK_TYPE, query->status.description); break; } if (!qd_parse_is_map(in_body)) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = "Body of request must be a map"; qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_AUTOLINK_TYPE, query->status.description); break; } // // Extract the fields from the request // qd_parsed_field_t *addr_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_ADDR]); qd_parsed_field_t *dir_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_DIR]); qd_parsed_field_t *phase_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_PHASE]); qd_parsed_field_t *connection_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_CONNECTION]); qd_parsed_field_t *container_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_CONTAINER_ID]); // // Addr and dir fields are mandatory. Fail if they're not both here. // if (!addr_field || !dir_field) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = "addr and dir fields are mandatory"; qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_AUTOLINK_TYPE, query->status.description); break; } qd_direction_t dir; const char *error = qdra_auto_link_direction_CT(dir_field, &dir); if (error) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = error; qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_AUTOLINK_TYPE, query->status.description); break; } // // Use the specified phase if present. Otherwise default based on the direction: // Phase 0 for outgoing links and phase 1 for incoming links. // int phase = phase_field ? qd_parse_as_int(phase_field) : (dir == QD_OUTGOING ? 0 : 1); // // Validate the phase // if (phase < 0 || phase > 9) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = "autoLink phase must be between 0 and 9"; qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_AUTOLINK_TYPE, query->status.description); break; } // // The request is good. Create the entity. // bool is_container = !!container_field; qd_parsed_field_t *in_use_conn = is_container ? container_field : connection_field; al = qdr_route_add_auto_link_CT(core, name, addr_field, dir, phase, in_use_conn, is_container); // // Compose the result map for the response. // if (query->body) { qd_compose_start_map(query->body); for (int col = 0; col < QDR_CONFIG_AUTO_LINK_COLUMN_COUNT; col++) qdr_config_auto_link_insert_column_CT(al, col, query->body, true); qd_compose_end_map(query->body); } query->status = QD_AMQP_CREATED; break; } // // Enqueue the response if there is a body. If there is no body, this is a management // operation created internally by the configuration file parser. // if (query->body) { // // If there was an error in processing the create, insert a NULL value into the body. // if (query->status.status / 100 > 2) qd_compose_insert_null(query->body); qdr_agent_enqueue_response_CT(core, query); } else { if (query->status.status / 100 > 2) qd_log(core->log, QD_LOG_ERROR, "Error configuring linkRoute: %s", query->status.description); qdr_query_free(query); } }
void qdra_config_link_route_create_CT(qdr_core_t *core, qd_field_iterator_t *name, qdr_query_t *query, qd_parsed_field_t *in_body) { while (true) { // // Ensure there isn't a duplicate name and that the body is a map // qdr_link_route_t *lr = DEQ_HEAD(core->link_routes); while (lr) { if (name && lr->name && qd_field_iterator_equal(name, (const unsigned char*) lr->name)) break; lr = DEQ_NEXT(lr); } if (!!lr) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = "Name conflicts with an existing entity"; break; } if (!qd_parse_is_map(in_body)) { query->status = QD_AMQP_BAD_REQUEST; break; } // // Extract the fields from the request // qd_parsed_field_t *prefix_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_PREFIX]); qd_parsed_field_t *distrib_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_DISTRIBUTION]); qd_parsed_field_t *connection_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_CONNECTION]); qd_parsed_field_t *container_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_CONTAINER_ID]); qd_parsed_field_t *dir_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_DIR]); // // Prefix and dir fields are mandatory. Fail if they're not both here. // if (!prefix_field || !dir_field) { query->status = QD_AMQP_BAD_REQUEST; break; } qd_direction_t dir; const char *error = qdra_link_route_direction_CT(dir_field, &dir); if (error) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = error; break; } qd_address_treatment_t trt; error = qdra_link_route_treatment_CT(distrib_field, &trt); if (error) { query->status = QD_AMQP_BAD_REQUEST; query->status.description = error; break; } // // The request is good. Create the entity. // bool is_container = !!container_field; qd_parsed_field_t *in_use_conn = is_container ? container_field : connection_field; lr = qdr_route_add_link_route_CT(core, name, prefix_field, in_use_conn, is_container, trt, dir); // // Compose the result map for the response. // if (query->body) { qd_compose_start_map(query->body); for (int col = 0; col < QDR_CONFIG_LINK_ROUTE_COLUMN_COUNT; col++) qdr_config_link_route_insert_column_CT(lr, col, query->body, true); qd_compose_end_map(query->body); } query->status = QD_AMQP_CREATED; break; } // // Enqueue the response if there is a body. If there is no body, this is a management // operation created internally by the configuration file parser. // if (query->body) { // // If there was an error in processing the create, insert a NULL value into the body. // if (query->status.status / 100 > 2) qd_compose_insert_null(query->body); qdr_agent_enqueue_response_CT(core, query); } else { if (query->status.status / 100 > 2) qd_log(core->log, QD_LOG_ERROR, "Error configuring linkRoute: %s", query->status.description); qdr_query_free(query); } }
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(); }