in src/router_core/agent_config_link_route.c [392:546]
void qdra_config_link_route_create_CT(qdr_core_t *core,
qd_iterator_t *name,
qdr_query_t *query,
qd_parsed_field_t *in_body)
{
char *pattern = NULL;
while (true) {
//
// Ensure there isn't a duplicate name and that the body is a map
//
qdr_link_route_t *lr = 0;
if (name) {
qd_iterator_view_t iter_view = qd_iterator_get_view(name);
qd_iterator_annotate_prefix(name, CONFIG_LINK_ROUTE_PREFIX);
qd_iterator_reset_view(name, ITER_VIEW_ADDRESS_HASH);
qd_hash_retrieve(core->addr_lr_al_hash, name, (void**) &lr);
qd_iterator_reset_view(name, iter_view);
}
if (!!lr) {
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_LINKROUTE_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_LINKROUTE_TYPE, query->status.description);
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 *pattern_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_PATTERN]);
qd_parsed_field_t *add_prefix_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_ADD_EXTERNAL_PREFIX]);
qd_parsed_field_t *del_prefix_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_DEL_EXTERNAL_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_DIRECTION]);
if (! dir_field) {
dir_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_DIR]);
if (dir_field)
qd_log(core->agent_log, QD_LOG_WARNING, "The 'dir' attribute of linkRoute has been deprecated. Use 'direction' instead");
}
//
// Both connection and containerId cannot be specified because both can represent different connections. Only one those
// can be specified.
//
if (connection_field && container_field) {
query->status = QD_AMQP_BAD_REQUEST;
query->status.description = "Both connection and containerId cannot be specified. Specify only one";
qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_LINKROUTE_TYPE, query->status.description);
break;
}
//
// The direction field is mandatory.
// Either a prefix or a pattern field is mandatory. However prefix and pattern
// are mutually exclusive. Fail if either both or none are given.
//
const char *msg = NULL;
if (!dir_field) {
msg = "No 'direction' attribute provided - it is mandatory";
} else if (!prefix_field && !pattern_field) {
msg = "Either a 'prefix' or 'pattern' attribute must be provided";
} else if (prefix_field && pattern_field) {
msg = "Cannot specify both a 'prefix' and a 'pattern' attribute";
}
if (msg) {
query->status = QD_AMQP_BAD_REQUEST;
query->status.description = msg;
qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_LINKROUTE_TYPE, query->status.description);
break;
}
// validate the pattern/prefix, add "/#" if prefix
pattern = qdra_config_address_validate_pattern_CT((prefix_field) ? prefix_field : pattern_field,
!!prefix_field,
&msg);
if (!pattern) {
query->status = QD_AMQP_BAD_REQUEST;
query->status.description = msg;
qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_LINKROUTE_TYPE, query->status.description);
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;
qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_LINKROUTE_TYPE, query->status.description);
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;
qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s", CONFIG_LINKROUTE_TYPE, query->status.description);
break;
}
//
// The request is good. Create the entity.
//
lr = qdr_route_add_link_route_CT(core, name, pattern, !!prefix_field,
add_prefix_field, del_prefix_field,
container_field, connection_field,
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);
}
free(pattern);
}