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 ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { DDS::DomainParticipantFactory_var dpf = DDS::DomainParticipantFactory::_nil(); DDS::DomainParticipant_var participant = DDS::DomainParticipant::_nil(); try { QuantLibAddinCpp::initializeAddin(); boost::gregorian::date date ( boost::gregorian::from_undelimited_string( "20111019" ) ); long evaluationDate = QuantLib::Date( date.day(), QuantLib::Month(date.month().as_number()), date.year() ).serialNumber(); QuantLibAddinCpp::qlSettingsSetEvaluationDate(evaluationDate, OH_NULL); std::string ticker; // Initialize, and create a DomainParticipant dpf = TheParticipantFactoryWithArgs(argc, argv); qldds_utils::BasicDomainParticipant participant( dpf, EQUITY_OPTIONS_DOMAIN_ID ); participant.createPublisher(); participant.createSubscriber(); DDS::DomainParticipant_var dp = participant.getDomainParticipant(); ACE_Get_Opt cmd_opts( argc, argv, ":s:" ); int option; while ( (option = cmd_opts()) != EOF ) { switch( option ) { case 's' : ticker = cmd_opts.opt_arg(); break; } } // Topics // setting up qlBlackConstantVols Topic DDS::Topic_var ql_black_constant_vols_topic = participant.createTopicAndRegisterType < qlBlackConstantVolsTypeSupport_var, qlBlackConstantVolsTypeSupportImpl > ( QL_BLACK_CONSTANT_VOLS_TOPIC_NAME ); // setting up qlGeneralizedBlackScholesProcesses Topic DDS::Topic_var ql_generalized_black_scholes_processes_topic = participant.createTopicAndRegisterType < qlGeneralizedBlackScholesProcessesTypeSupport_var, qlGeneralizedBlackScholesProcessesTypeSupportImpl > ( QL_GENERALIZED_BLACK_SCHOLES_PROCESSES_TOPIC_NAME ); // setting up qlStrikedTypePayoff Topic DDS::Topic_var ql_striked_type_payoffs_topic = participant.createTopicAndRegisterType < qlStrikedTypePayoffsTypeSupport_var, qlStrikedTypePayoffsTypeSupportImpl > ( QL_STRIKED_TYPE_PAYOFFS_TOPIC_NAME ); // setting up qlEuropeanExercises Topic DDS::Topic_var ql_european_exercises_topic = participant.createTopicAndRegisterType < qlEuropeanExercisesTypeSupport_var, qlEuropeanExercisesTypeSupportImpl > ( QL_EUROPEAN_EXERCISES_TOPIC_NAME ); StraddleSetupTypeSupport_var ts_res = new StraddleSetupTypeSupportImpl; if ( ts_res->register_type(dp, "") != DDS::RETCODE_OK ) { std::cout << "Registration of the Topic FAILED!!!!" << std::endl; } CORBA::String_var type_name = ts_res->get_type_name(); std::cout << "Type Name : " << type_name << std::endl; std::stringstream multi_topic_select; multi_topic_select << "SELECT ticker, putVols, callVols, putPayoffs, callPayoffs, process, exercises FROM "<< QL_BLACK_CONSTANT_VOLS_TOPIC_NAME << " NATURAL JOIN " << QL_GENERALIZED_BLACK_SCHOLES_PROCESSES_TOPIC_NAME << " NATURAL JOIN " << QL_STRIKED_TYPE_PAYOFFS_TOPIC_NAME << " NATURAL JOIN " << QL_EUROPEAN_EXERCISES_TOPIC_NAME << " WHERE ticker = '" << ticker << "'"; std::cout << multi_topic_select.str() << std::endl; DDS::MultiTopic_var mt = dp->create_multitopic("MyMultiTopic", type_name, multi_topic_select.str().c_str(), DDS::StringSeq()); if ( CORBA::is_nil( mt ) ) std::cout << "MultiTopic Subscribtion failed.!!!!" << mt << std::endl; DDS::Subscriber_var sub = participant.getSubscriber(); std::cout << "Creating Data Reader"<< std::endl; DDS::DataReader_var dr = sub->create_datareader(mt, DATAREADER_QOS_DEFAULT, 0, ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); std::cout << "Done..."<< std::endl; DDS::WaitSet_var ws = new DDS::WaitSet; DDS::ReadCondition_var rc = dr->create_readcondition( DDS::ANY_SAMPLE_STATE, DDS::ANY_VIEW_STATE, DDS::ANY_INSTANCE_STATE); ws->attach_condition(rc); DDS::Duration_t infinite = { DDS::DURATION_INFINITE_SEC, DDS::DURATION_INFINITE_NSEC}; DDS::ConditionSeq active; int ret = ws->wait(active, infinite); if (ret != DDS::RETCODE_OK) return false; ws->detach_condition(rc); // setting up topic for Straddles DDS::Topic_var straddles_topic = participant.createTopicAndRegisterType < StraddlesTypeSupport_var, StraddlesTypeSupportImpl > ( STRADDLES_TOPIC_NAME ); StraddlesDataWriter_var straddles_dw = participant.createDataWriter < StraddlesDataWriter_var, StraddlesDataWriter > ( straddles_topic ); int calculation_performed = 0; do { StraddleSetupDataReader_var res_dr = StraddleSetupDataReader::_narrow(dr); StraddleSetupSeq data; DDS::SampleInfoSeq info; int ret = res_dr->take_w_condition(data, info, DDS::LENGTH_UNLIMITED, rc); if (ret == DDS::RETCODE_OK) { qlBlackConstantVolMatrix& putVols = data[0].putVols; qlStrikedTypePayoffSeq& putPayoffs = data[0].putPayoffs; qlBlackConstantVolMatrix& callVols = data[0].callVols; qlStrikedTypePayoffSeq& callPayoffs = data[0].callPayoffs; processes::qlGeneralizedBlackScholesProcess& process = data[0].process; qlEuropeanExerciseSeq& exercises = data[0].exercises; Straddles straddles; straddles.ticker = CORBA::string_dup( ticker.c_str() ); straddles.underlying = data[0].process.Underlying; int strike_count = putPayoffs.length() + callPayoffs.length(); int exercises_count = exercises.length(); straddles.options.length( strike_count * exercises_count ); int priced_options = 0; price( ticker, putVols, putPayoffs, process, exercises, straddles, priced_options ); price( ticker, callVols, callPayoffs, process, exercises, straddles, priced_options ); ACE_DEBUG( (LM_INFO, "(%T|%P|%t) Publishing Straddles for ticker : %s trading @%f\n", ticker.c_str(), data[0].process.Underlying ) ); int ret = straddles_dw->write( straddles, DDS::HANDLE_NIL ); if (ret != DDS::RETCODE_OK) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: Publishing Straddles for ticker : %s failed %d.\n"), ticker.c_str(), ret)); } calculation_performed++; } } while ( calculation_performed < 30 ); cout << "Exiting..." << endl; } catch (CORBA::Exception& e) { cerr << "Exception caught in main.cpp:" << endl << e << endl; ACE_OS::exit(1); } TheServiceParticipant->shutdown(); return 0; }