void qdr_core_unbind_address_link_CT(qdr_core_t *core, qdr_address_t *addr, qdr_link_t *link) { link->owning_addr = 0; if (link->link_direction == QD_OUTGOING) { qdr_del_link_ref(&addr->rlinks, link, QDR_LINK_LIST_CLASS_ADDRESS); if (DEQ_SIZE(addr->rlinks) == 0) { const char *key = (const char*) qd_hash_key_by_handle(addr->hash_handle); if (key && (*key == QD_ITER_HASH_PREFIX_MOBILE || *key == QD_ITER_HASH_PREFIX_EDGE_SUMMARY)) qdr_post_mobile_removed_CT(core, key); qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_LOCAL_DEST, addr); } else if (DEQ_SIZE(addr->rlinks) == 1 && qd_bitmask_cardinality(addr->rnodes) == 0) qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_ONE_LOCAL_DEST, addr); } else { bool removed = qdr_del_link_ref(&addr->inlinks, link, QDR_LINK_LIST_CLASS_ADDRESS); if (removed) { if (DEQ_SIZE(addr->inlinks) == 0) { qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_SOURCE, addr); if (!!addr->fallback && !link->fallback) qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_SOURCE, addr->fallback); } else if (DEQ_SIZE(addr->inlinks) == 1) { qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_ONE_SOURCE, addr); if (!!addr->fallback && !link->fallback) qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_ONE_SOURCE, addr->fallback); } } } }
void qdr_core_bind_address_link_CT(qdr_core_t *core, qdr_address_t *addr, qdr_link_t *link) { const char *key = (const char*) qd_hash_key_by_handle(addr->hash_handle); link->owning_addr = addr; if (key && (*key == QD_ITER_HASH_PREFIX_MOBILE)) link->phase = (int) (key[1] - '0'); if (link->link_direction == QD_OUTGOING) { qdr_add_link_ref(&addr->rlinks, link, QDR_LINK_LIST_CLASS_ADDRESS); if (DEQ_SIZE(addr->rlinks) == 1) { if (key && (*key == QD_ITER_HASH_PREFIX_EDGE_SUMMARY || *key == QD_ITER_HASH_PREFIX_MOBILE)) qdr_post_mobile_added_CT(core, key, addr->treatment); qdr_addr_start_inlinks_CT(core, addr); qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_BECAME_LOCAL_DEST, addr); } else if (DEQ_SIZE(addr->rlinks) == 2 && qd_bitmask_cardinality(addr->rnodes) == 0) qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_TWO_DEST, addr); } else { // link->link_direction == QD_INCOMING qdr_add_link_ref(&addr->inlinks, link, QDR_LINK_LIST_CLASS_ADDRESS); if (DEQ_SIZE(addr->inlinks) == 1) { qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_BECAME_SOURCE, addr); if (!!addr->fallback && !link->fallback) qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_BECAME_SOURCE, addr->fallback); } else if (DEQ_SIZE(addr->inlinks) == 2) { qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_TWO_SOURCE, addr); if (!!addr->fallback && !link->fallback) qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_TWO_SOURCE, addr->fallback); } } }
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; } }