in src/router_core/agent_config_auto_link.c [372:513]
void qdra_config_auto_link_create_CT(qdr_core_t *core,
qd_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 = 0;
if (name) {
qd_iterator_view_t iter_view = qd_iterator_get_view(name);
qd_iterator_annotate_prefix(name, CONFIG_AUTO_LINK_PREFIX);
qd_iterator_reset_view(name, ITER_VIEW_ADDRESS_HASH);
qd_hash_retrieve(core->addr_lr_al_hash, name, (void**) &al);
qd_iterator_reset_view(name, iter_view);
}
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_ADDRESS]);
if (!addr_field) {
addr_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_ADDR]);
if (addr_field)
qd_log(core->agent_log, QD_LOG_WARNING, "The 'addr' attribute of autoLink has been deprecated. Use 'address' instead");
}
qd_parsed_field_t *dir_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_DIRECTION]);
if (! dir_field) {
dir_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_DIR]);
if (dir_field)
qd_log(core->agent_log, QD_LOG_WARNING, "The 'dir' attribute of autoLink has been deprecated. Use 'direction' instead");
}
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]);
qd_parsed_field_t *fallback_field = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_FALLBACK]);
qd_parsed_field_t *external_addr = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_EXT_ADDRESS]);
if (!external_addr) {
external_addr = qd_parse_value_by_key(in_body, qdr_config_auto_link_columns[QDR_CONFIG_AUTO_LINK_EXT_ADDR]);
if (external_addr)
qd_log(core->agent_log, QD_LOG_WARNING, "The 'externalAddr' attribute of autoLink has been deprecated. Use 'externalAddress' instead");
}
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_AUTOLINK_TYPE, query->status.description);
break;
}
bool fallback = !!fallback_field ? qd_parse_as_bool(fallback_field) : false;
//
// Addr and direction fields are mandatory. Fail if they're not both here.
//
if (!addr_field || !dir_field) {
query->status = QD_AMQP_BAD_REQUEST;
query->status.description = "address and direction 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.
//
long phase = phase_field ? qd_parse_as_long(phase_field) : ((dir == QD_OUTGOING || !!fallback) ? 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.
//
al = qdr_route_add_auto_link_CT(core, name, addr_field, dir, phase, container_field, connection_field, external_addr, fallback);
//
// 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);
}
}