qdr_auto_link_t *qdr_route_add_auto_link_CT(qdr_core_t *core, qd_iterator_t *name, qd_parsed_field_t *addr_field, qd_direction_t dir, int phase, qd_parsed_field_t *container_field, qd_parsed_field_t *connection_field, qd_parsed_field_t *external_addr) { qdr_auto_link_t *al = new_qdr_auto_link_t(); // // Set up the auto_link structure // ZERO(al); al->identity = qdr_identifier(core); al->name = name ? (char*) qd_iterator_copy(name) : 0; al->dir = dir; al->phase = phase; al->state = QDR_AUTO_LINK_STATE_INACTIVE; al->external_addr = external_addr ? (char*) qd_iterator_copy(qd_parse_raw(external_addr)) : 0; // // Find or create an address for the auto_link destination // qd_iterator_t *iter = qd_parse_raw(addr_field); qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_iterator_annotate_phase(iter, (char) phase + '0'); qd_hash_retrieve(core->addr_hash, iter, (void*) &al->addr); if (!al->addr) { al->addr = qdr_address_CT(core, qdr_treatment_for_address_CT(core, 0, iter, 0, 0)); DEQ_INSERT_TAIL(core->addrs, al->addr); qd_hash_insert(core->addr_hash, iter, al->addr, &al->addr->hash_handle); } al->addr->ref_count++; // // Find or create a connection identifier structure for this auto_link // if (container_field || connection_field) { al->conn_id = qdr_route_declare_id_CT(core, qd_parse_raw(container_field), qd_parse_raw(connection_field)); DEQ_INSERT_TAIL_N(REF, al->conn_id->auto_link_refs, al); qdr_connection_ref_t * cref = DEQ_HEAD(al->conn_id->connection_refs); while (cref) { qdr_auto_link_activate_CT(core, al, cref->conn); cref = DEQ_NEXT(cref); } } // // Add the auto_link to the core list // DEQ_INSERT_TAIL(core->auto_links, al); return al; }
char *qdr_field_copy(qdr_field_t *field) { if (!field || !field->iterator) return 0; return (char*) qd_iterator_copy(field->iterator); }
static char* test_view_address_with_space(void *context) { struct {const char *addr; const char *view;} cases[] = { {"amqp:/link-target", "M0test.vhost.link-target"}, {"amqp:/domain/link-target", "M0test.vhost.domain/link-target"}, {"domain/link-target", "M0test.vhost.domain/link-target"}, {"bbc79fb3-e1fd-4a08-92b2-9a2de232b558", "M0test.vhost.bbc79fb3-e1fd-4a08-92b2-9a2de232b558"}, {0, 0} }; int idx; for (idx = 0; cases[idx].addr; idx++) { qd_iterator_t *iter = qd_iterator_string(cases[idx].addr, ITER_VIEW_ADDRESS_HASH); qd_iterator_annotate_space(iter, "test.vhost.", 11); if (!qd_iterator_equal(iter, (unsigned char*) cases[idx].view)) { char *got = (char*) qd_iterator_copy(iter); snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed. Expected '%s', got '%s'", cases[idx].addr, cases[idx].view, got); return fail_text; } if (qd_iterator_length(iter) != strlen(cases[idx].view)) { snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed. Length %d, iter_length returned %d", cases[idx].addr, (int) strlen(cases[idx].view), (int) qd_iterator_length(iter)); return fail_text; } qd_iterator_free(iter); } return 0; }
static char* test_view_address_hash_override(void *context) { struct {const char *addr; const char *view;} cases[] = { {"amqp:/link-target", "Clink-target"}, {"amqp:/domain/link-target", "Cdomain/link-target"}, {"domain/link-target", "Cdomain/link-target"}, {"bbc79fb3-e1fd-4a08-92b2-9a2de232b558", "Cbbc79fb3-e1fd-4a08-92b2-9a2de232b558"}, {0, 0} }; int idx; for (idx = 0; cases[idx].addr; idx++) { qd_iterator_t *iter = qd_iterator_string(cases[idx].addr, ITER_VIEW_ADDRESS_HASH); qd_iterator_annotate_prefix(iter, 'C'); if (!qd_iterator_equal(iter, (unsigned char*) cases[idx].view)) { char *got = (char*) qd_iterator_copy(iter); snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed. Expected '%s', got '%s'", cases[idx].addr, cases[idx].view, got); return fail_text; } qd_iterator_free(iter); } return 0; }
qdr_link_route_t *qdr_route_add_link_route_CT(qdr_core_t *core, qd_iterator_t *name, qd_parsed_field_t *prefix_field, qd_parsed_field_t *container_field, qd_parsed_field_t *connection_field, qd_address_treatment_t treatment, qd_direction_t dir) { qdr_link_route_t *lr = new_qdr_link_route_t(); // // Set up the link_route structure // ZERO(lr); lr->identity = qdr_identifier(core); lr->name = name ? (char*) qd_iterator_copy(name) : 0; lr->dir = dir; lr->treatment = treatment; // // Find or create an address for link-attach routing // qd_iterator_t *iter = qd_parse_raw(prefix_field); qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_iterator_annotate_prefix(iter, dir == QD_INCOMING ? 'C' : 'D'); qd_hash_retrieve(core->addr_hash, iter, (void*) &lr->addr); if (!lr->addr) { lr->addr = qdr_address_CT(core, treatment); DEQ_INSERT_TAIL(core->addrs, lr->addr); qd_hash_insert(core->addr_hash, iter, lr->addr, &lr->addr->hash_handle); } lr->addr->ref_count++; // // Find or create a connection identifier structure for this link route // if (container_field || connection_field) { lr->conn_id = qdr_route_declare_id_CT(core, qd_parse_raw(container_field), qd_parse_raw(connection_field)); DEQ_INSERT_TAIL_N(REF, lr->conn_id->link_route_refs, lr); qdr_connection_ref_t * cref = DEQ_HEAD(lr->conn_id->connection_refs); while (cref) { qdr_link_route_activate_CT(core, lr, cref->conn); cref = DEQ_NEXT(cref); } } // // Add the link route to the core list // DEQ_INSERT_TAIL(core->link_routes, lr); return lr; }
static char* view_address_hash(void *context, qd_iterator_t *iter, const char *addr, const char *view) { qd_iterator_annotate_phase(iter, '1'); if (!qd_iterator_equal(iter, (unsigned char*) view)) { char *got = (char*) qd_iterator_copy(iter); snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed. Expected '%s', got '%s'", addr, view, got); return fail_text; } return 0; }
static char* test_view_node_hash(void *context) { struct {const char *addr; const char *view;} cases[] = { {"area/router", "Aarea"}, {"my-area/router", "Rrouter"}, {"my-area/my-router", "Rmy-router"}, {0, 0} }; int idx; for (idx = 0; cases[idx].addr; idx++) { qd_iterator_t *iter = qd_iterator_string(cases[idx].addr, ITER_VIEW_NODE_HASH); if (!qd_iterator_equal(iter, (unsigned char*) cases[idx].view)) { char *got = (char*) qd_iterator_copy(iter); snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed. Expected '%s', got '%s'", cases[idx].addr, cases[idx].view, got); return fail_text; qd_iterator_free(iter); } qd_iterator_free(iter); } return 0; }
static char *test_map(void *context) { static char error[1000]; const char *data = "\xd1\x00\x00\x00\x2d\x00\x00\x00\x06" // map32, 6 items "\xa3\x05\x66irst\xa1\x0evalue_of_first" // (23) "first":"value_of_first" "\xa3\x06second\x52\x20" // (10) "second":32 "\xa3\x05third\x41"; // (8) "third":true int data_len = 50; qd_iterator_t *data_iter = qd_iterator_binary(data, data_len, ITER_VIEW_ALL); qd_parsed_field_t *field = qd_parse(data_iter); if (!qd_parse_ok(field)) { snprintf(error, 1000, "Parse failed: %s", qd_parse_error(field)); qd_iterator_free(data_iter); qd_parse_free(field); return error; } if (!qd_parse_is_map(field)) { qd_iterator_free(data_iter); qd_parse_free(field); return "Expected field to be a map"; } uint32_t count = qd_parse_sub_count(field); if (count != 3) { snprintf(error, 1000, "Expected sub-count==3, got %"PRIu32, count); qd_iterator_free(data_iter); qd_parse_free(field); return error; } qd_parsed_field_t *key_field = qd_parse_sub_key(field, 0); qd_iterator_t *key_iter = qd_parse_raw(key_field); qd_iterator_t *typed_iter = qd_parse_typed(key_field); if (!qd_iterator_equal(key_iter, (unsigned char*) "first")) { unsigned char *result = qd_iterator_copy(key_iter); snprintf(error, 1000, "First key: expected 'first', got '%s'", result); free (result); return error; } if (!qd_iterator_equal(typed_iter, (unsigned char*) "\xa3\x05\x66irst")) return "Incorrect typed iterator on first-key"; qd_parsed_field_t *val_field = qd_parse_sub_value(field, 0); qd_iterator_t *val_iter = qd_parse_raw(val_field); typed_iter = qd_parse_typed(val_field); if (!qd_iterator_equal(val_iter, (unsigned char*) "value_of_first")) { unsigned char *result = qd_iterator_copy(val_iter); snprintf(error, 1000, "First value: expected 'value_of_first', got '%s'", result); free (result); return error; } if (!qd_iterator_equal(typed_iter, (unsigned char*) "\xa1\x0evalue_of_first")) return "Incorrect typed iterator on first-key"; key_field = qd_parse_sub_key(field, 1); key_iter = qd_parse_raw(key_field); if (!qd_iterator_equal(key_iter, (unsigned char*) "second")) { unsigned char *result = qd_iterator_copy(key_iter); snprintf(error, 1000, "Second key: expected 'second', got '%s'", result); free (result); return error; } val_field = qd_parse_sub_value(field, 1); if (qd_parse_as_uint(val_field) != 32) { snprintf(error, 1000, "Second value: expected 32, got %"PRIu32, qd_parse_as_uint(val_field)); return error; } key_field = qd_parse_sub_key(field, 2); key_iter = qd_parse_raw(key_field); if (!qd_iterator_equal(key_iter, (unsigned char*) "third")) { unsigned char *result = qd_iterator_copy(key_iter); snprintf(error, 1000, "Third key: expected 'third', got '%s'", result); free (result); return error; } val_field = qd_parse_sub_value(field, 2); if (!qd_parse_as_bool(val_field)) { snprintf(error, 1000, "Third value: expected true"); return error; } qd_iterator_free(data_iter); qd_parse_free(field); return 0; }