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; }
int run_test_instance(DDS::DomainParticipant_ptr dp) { using namespace DDS; using namespace OpenDDS::DCPS; using namespace Messenger; WaitSet_var ws = new WaitSet; MessageTypeSupport_var ts = new MessageTypeSupportImpl; ts->register_type(dp, ""); CORBA::String_var type_name = ts->get_type_name(); Topic_var topic = dp->create_topic("MyTopic", type_name, TOPIC_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); Publisher_var pub = dp->create_publisher(PUBLISHER_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); DataWriter_var dw = pub->create_datawriter(topic, DATAWRITER_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); Subscriber_var sub = dp->create_subscriber(SUBSCRIBER_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); DataReader_var dr = sub->create_datareader(topic, DATAREADER_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); StatusCondition_var dw_sc = dw->get_statuscondition(); dw_sc->set_enabled_statuses(PUBLICATION_MATCHED_STATUS); ws->attach_condition(dw_sc); Duration_t infinite = {DURATION_INFINITE_SEC, DURATION_INFINITE_NSEC}; ConditionSeq active; ReturnCode_t ret = ws->wait(active, infinite); if (ret != RETCODE_OK) return ret; ret = ws->detach_condition(dw_sc); if (ret != RETCODE_OK) return ret; MessageDataWriter_var mdw = MessageDataWriter::_narrow(dw); Message msg = {0}; for (int i(0); i < 12; ++i) { ++msg.subject_id; ret = mdw->write(msg, HANDLE_NIL); if (ret != RETCODE_OK) return ret; } ReadCondition_var dr_rc = dr->create_readcondition(NOT_READ_SAMPLE_STATE, NEW_VIEW_STATE, ALIVE_INSTANCE_STATE); ReadCondition_var dr_rc2 = dr->create_readcondition(ANY_SAMPLE_STATE, ANY_VIEW_STATE, NOT_ALIVE_DISPOSED_INSTANCE_STATE); ws->attach_condition(dr_rc); ws->attach_condition(dr_rc2); MessageDataReader_var mdr = MessageDataReader::_narrow(dr); bool passed = true, done = false; while (!done) { ret = ws->wait(active, infinite); if (ret != RETCODE_OK) { passed = false; break; } cout << "wait returned" << endl; for (CORBA::ULong i(0); i < active.length(); ++i) { if (active[i] == dr_rc) { // To test both take_w_condition and // take_next_instance_w_condition, we'll limit the "take" to 3 // samples and then use take_next_instance_w_condition. MessageSeq data; SampleInfoSeq info; ret = mdr->take_w_condition(data, info, 3, dr_rc); if (ret == RETCODE_NO_DATA) break; if (ret != RETCODE_OK) { cout << "ERROR: take_w_condition returned " << ret << endl; passed = false; done = true; } InstanceHandle_t handle = HANDLE_NIL; received_data(data, mdw, msg); handle = info[info.length() - 1].instance_handle; if (handle == HANDLE_NIL) { cout << "ERROR: instance handle is nil" << endl; passed = false; done = true; break; } cout << "testing take_instance_w_condition" << endl; while (true) { ret = mdr->take_instance_w_condition(data, info, 1, handle, dr_rc); if (ret == RETCODE_NO_DATA) break; if (ret != RETCODE_OK) { cout << "ERROR: take_instance_w_condition returned " << ret << endl; passed = false; done = true; break; } received_data(data, mdw, msg); } } else if (active[i] == dr_rc2) { cout << "an instance has been disposed, exiting" << endl; done = true; } } } ws->detach_condition(dr_rc); ws->detach_condition(dr_rc2); dp->delete_contained_entities(); return passed ? 0 : 1; }
void Transceiver::create(const transceiverDef& def) { m_def = def; // cout << "Transceiver::create(" << partition_id() << ", " << m_def.transceiver_id << ")" << endl; // setup QueryCondition for reading this Transceiver's Qos stringstream id; id << m_def.transceiver_id; StringSeq params; params.length(1); params[0] = id.str().c_str(); m_qos_query.create(ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE, "transceiver_id = %0", params); // setup Transceiver topic set_topics(); // read initial Qos transceiverQosSeq qoss; SampleInfoSeq infos; // REVISIT - read or take? ReturnCode_t retcode = qos_reader()->read_w_condition(qoss, infos, 1, m_qos_query); if (retcode == RETCODE_NO_DATA) { // no Qos instance to read, so initialize and write m_qos.group_id = m_def.group_id; m_qos.transceiver_id = m_def.transceiver_id; m_qos.partition_id = m_def.partition_id; m_qos.writer_qos.latency_budget.duration.sec = 0; m_qos.writer_qos.latency_budget.duration.nanosec = 0; m_qos.writer_qos.transport_priority.value = 0; m_qos.reader_qos.history.depth = 1; m_qos.reader_qos.latency_budget.duration.sec = 0; m_qos.reader_qos.latency_budget.duration.nanosec = 0; retcode = qos_writer()->write(m_qos, 0); qos_writer().check(retcode, "transceiverQosDataWriter::write"); } else { qos_reader().check(retcode, "transceiverQosDataReader::read_w_condition"); assert(qoss.length() == 1); assert(infos.length() == 1); m_qos = qoss[0]; assert(m_qos.group_id == m_def.group_id); assert(m_qos.transceiver_id == m_def.transceiver_id); assert(m_qos.partition_id == m_def.partition_id); } qos_reader()->return_loan(qoss, infos); set_qos(); // start threads m_writer_active = true; m_writer_thread.create(&Transceiver::writer_thread); m_reader_active = true; m_reader_thread.create(&Transceiver::reader_thread); m_report_active = true; m_report_thread.create(&Transceiver::report_thread); }