bool run_multitopic_test(const Publisher_var& pub, const Subscriber_var& sub) { DomainParticipant_var sub_dp = sub->get_participant(); // Writer-side setup Writer<LocationInfo> location(pub, "Location", sub_dp); Writer<PlanInfo> flightplan(pub, "FlightPlan", sub_dp); Writer<MoreInfo> more(pub, "More", sub_dp); Writer<UnrelatedInfo> unrelated(pub, "Unrelated", sub_dp); MoreInfoDataWriter_var midw = MoreInfoDataWriter::_narrow(more.dw_); // Reader-side setup ResultingTypeSupport_var ts_res = new ResultingTypeSupportImpl; check(ts_res->register_type(sub_dp, "")); CORBA::String_var type_name = ts_res->get_type_name(); MoreInfo mi; DDS::DataReader_var dr; for (int i = 0; i < N_ITERATIONS; ++i) { MultiTopic_var mt = sub_dp->create_multitopic("MyMultiTopic", type_name, "SELECT flight_name, x, y, z AS height, more, misc " "FROM Location NATURAL JOIN FlightPlan NATURAL JOIN More NATURAL JOIN " "Unrelated WHERE height < 1000 AND x<23", StringSeq()); if (!mt) return false; dr = sub->create_datareader(mt, DATAREADER_QOS_DEFAULT, 0, DEFAULT_STATUS_MASK); // Write samples (Location) waitForMatch(location.dw_); LocationInfoDataWriter_var locdw = LocationInfoDataWriter::_narrow(location.dw_); LocationInfo sample = {100, 97, 23, 2, 3}; // filtered out (x < 23) ReturnCode_t ret = locdw->write(sample, HANDLE_NIL); if (ret != RETCODE_OK) return false; LocationInfo sample2 = {100, 96, 1, 2, 3000}; // filtered out (height < 1000) ret = locdw->write(sample2, HANDLE_NIL); if (ret != RETCODE_OK) return false; LocationInfo sample3 = {100, 99, 1, 2, 3}; ret = locdw->write(sample3, HANDLE_NIL); if (ret != RETCODE_OK) return false; LocationInfo sample3_5 = {100, 98, 4, 5, 6}; ret = locdw->write(sample3_5, HANDLE_NIL); if (ret != RETCODE_OK) return false; // Write samples (FlightPlan) waitForMatch(flightplan.dw_); PlanInfoDataWriter_var pidw = PlanInfoDataWriter::_narrow(flightplan.dw_); PlanInfo sample4; sample4.flight_id1 = 100; sample4.flight_id2 = 99; sample4.flight_name = "Flight 100-99"; sample4.tailno = "N12345"; ret = pidw->write(sample4, HANDLE_NIL); if (ret != RETCODE_OK) return false; PlanInfo sample4_1(sample4); sample4_1.flight_id2 = 97; sample4_1.flight_name = "Flight 100-97"; ret = pidw->write(sample4_1, HANDLE_NIL); if (ret != RETCODE_OK) return false; PlanInfo sample4_2(sample4); sample4_2.flight_id2 = 96; sample4_2.flight_name = "Flight 100-96"; ret = pidw->write(sample4_2, HANDLE_NIL); if (ret != RETCODE_OK) return false; // Write samples (More) waitForMatch(more.dw_); mi.flight_id1 = 12345; mi.more = "Shouldn't see this"; ret = midw->write(mi, HANDLE_NIL); if (ret != RETCODE_OK) return false; mi.flight_id1 = 100; mi.more = "Extra info for all flights with id1 == 100"; ret = midw->write(mi, HANDLE_NIL); if (ret != RETCODE_OK) return false; // Write samples (Unrelated) waitForMatch(unrelated.dw_); UnrelatedInfoDataWriter_var uidw = UnrelatedInfoDataWriter::_narrow(unrelated.dw_); UnrelatedInfo ui; ui.misc = "Misc"; ret = uidw->write(ui, HANDLE_NIL); if (ret != RETCODE_OK) return false; // Read resulting samples WaitSet_var ws = new WaitSet; ReadCondition_var rc = dr->create_readcondition(ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE); ws->attach_condition(rc); Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC}; ConditionSeq active; ret = ws->wait(active, infinite); if (ret != RETCODE_OK) return false; ws->detach_condition(rc); ResultingDataReader_var res_dr = ResultingDataReader::_narrow(dr); ResultingSeq data; SampleInfoSeq info; ret = res_dr->take_w_condition(data, info, LENGTH_UNLIMITED, rc); if (ret != RETCODE_OK) return false; if (data.length() > 1 || !info[0].valid_data) return false; std::cout << "Received: " << data[0].flight_id1 << '-' << data[0].flight_id2 << " \"" << data[0].flight_name << "\" " << data[0].x << " " << data[0].y << " " << data[0].height << " \"" << data[0].more << "\" \"" << data[0].misc << "\"" << std::endl; if (data[0].flight_id1 != sample4.flight_id1 || data[0].flight_id2 != sample4.flight_id2 || strcmp(data[0].flight_name, sample4.flight_name) || data[0].x != sample3.x || data[0].y != sample3.y || data[0].height != sample3.z || strcmp(data[0].more, mi.more) || strcmp(data[0].misc, ui.misc)) { return false; } // Check return get_key_value Resulting resulting_value; ret = res_dr->get_key_value(resulting_value, DDS::HANDLE_NIL); if (ret != RETCODE_BAD_PARAMETER) return false; data.length(0); info.length(0); ret = res_dr->read_w_condition(data, info, LENGTH_UNLIMITED, rc); dr->delete_readcondition(rc); if (ret != RETCODE_NO_DATA) return false; // Reader cleanup if (i != N_ITERATIONS - 1) { sub->delete_datareader(dr); waitForMatch(location.dw_, 0); waitForMatch(flightplan.dw_, 0); waitForMatch(more.dw_, 0); waitForMatch(unrelated.dw_, 0); sub_dp->delete_multitopic(mt); } } // Dispose ReturnCode_t ret = midw->dispose(mi, HANDLE_NIL); if (ret != RETCODE_OK) return false; ReadCondition_var rc = dr->create_readcondition(ANY_SAMPLE_STATE, ANY_VIEW_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE); WaitSet_var ws = new WaitSet; ws->attach_condition(rc); const Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC}; ConditionSeq active; ret = ws->wait(active, infinite); if (ret != RETCODE_OK) return false; ws->detach_condition(rc); ResultingDataReader_var res_dr = ResultingDataReader::_narrow(dr); ResultingSeq data; SampleInfoSeq info; ret = res_dr->read_w_condition(data, info, LENGTH_UNLIMITED, rc); dr->delete_readcondition(rc); if (ret != RETCODE_OK) return false; if (info[0].valid_data || info[0].instance_state != NOT_ALIVE_DISPOSED_INSTANCE_STATE) return false; return true; }