/** * @brief Construct a test system from the command line. */ TestMonitor::TestMonitor( int argc, ACE_TCHAR** argv, char** envp) : config_( argc, argv, envp) { /// DDS_RUN_DEBUG_LEVEL = 5; /// OpenDDS::DCPS::DCPS_debug_level = 5; // Grab a local reference to the factory to ensure that we perform the // operations - they should not get optimized away! Note that this // passes the arguments to the ORB initialization first, then strips // the DCPS arguments. ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: initializing the monitor.\n"))); ::DDS::DomainParticipantFactory_var factory = TheParticipantFactoryWithArgs( argc, argv); this->subscriberParticipant_.resize( this->config_.subscriberDomainSize(), ::DDS::DomainParticipant::_nil() ); this->publisherParticipant_.resize( this->config_.publisherDomainSize(), ::DDS::DomainParticipant::_nil() ); this->subscriber_.resize( this->config_.subscriberDomainSize(), ::DDS::Subscriber::_nil()); this->publisher_.resize( this->config_.publisherDomainSize(), ::DDS::Publisher::_nil()); this->readerTopic_.resize( this->config_.subscriberDomainSize(), ::DDS::Topic::_nil()); this->writerTopic_.resize( this->config_.publisherDomainSize(), ::DDS::Topic::_nil()); this->dataReader_.resize( this->config_.subscriberDomainSize(), ::DDS::DataReader::_nil()); this->dataWriter_.resize( this->config_.publisherDomainSize(), ::DDS::DataWriter::_nil()); this->listener_.resize( this->config_.subscriberDomainSize(), ::DDS::DataReaderListener::_nil()); this->forwarder_.resize( this->config_.subscriberDomainSize(), 0); if( signed(OpenDDS::DCPS::DCPS_debug_level) >= 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: Verbose == %C\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: Samples == %d\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: Type == %C\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: Transport Address == %s\n"), (this->config_.verbose()? "true": "false"), this->config_.samples(), this->config_.typeName().c_str(), this->config_.transportAddressName().c_str() )); for( int index = 0; index < this->config_.infoRepoIorSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: InforRepoIOR[ %d] == %C\n"), index, this->config_.infoRepoIor( index).c_str() )); } for( int index = 0; index < this->config_.readerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: readerTopicName[ %d] == %C\n"), index, this->config_.readerTopicName( index).c_str() )); } for( int index = 0; index < this->config_.writerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: writerTopicName[ %d] == %C\n"), index, this->config_.writerTopicName( index).c_str() )); } for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: subscriberDomain[ %d] == %d\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: using repository key %d\n"), index, this->config_.subscriberDomain( index), this->config_.domainToRepo( this->config_.subscriberDomain( index)) )); } for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T COMMANDLINE: publisherDomain[ %d] == %d\n") ACE_TEXT("(%P|%t) %T COMMANDLINE: using repository key %d\n"), index, this->config_.publisherDomain( index), this->config_.domainToRepo( this->config_.publisherDomain( index)) )); } } for( int index = 0; index < this->config_.infoRepoIorSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: loading repository %d.\n"), index )); TheServiceParticipant->set_repo_ior( this->config_.infoRepoIor( index).c_str(), index ); } // We only need to do binding if we receive InfoRepo IOR values on the // command line - otherwise this is done during configuration file // processing. if( this->config_.infoRepoIorSize() > 0) { for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding subscriber domain %d to repository %d.\n"), this->config_.subscriberDomain( index), this->config_.domainToRepo( this->config_.subscriberDomain( index)) )); TheServiceParticipant->set_repo_domain( this->config_.subscriberDomain( index), this->config_.domainToRepo( this->config_.subscriberDomain( index)) ); } for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding publisher domain %d to repository %d.\n"), this->config_.publisherDomain( index), this->config_.domainToRepo( this->config_.publisherDomain( index)) )); TheServiceParticipant->set_repo_domain( this->config_.publisherDomain( index), this->config_.domainToRepo( this->config_.publisherDomain( index)) ); } } // // Establish DomainParticipants for the subscription domains. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber participant in domain %d.\n"), this->config_.subscriberDomain( index) )); ParticipantMap::iterator where = this->participants_.find( this->config_.subscriberDomain( index)); if( where == this->participants_.end()) { this->participants_[ this->config_.subscriberDomain( index)] = factory->create_participant( this->config_.subscriberDomain( index), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->participants_[ this->config_.subscriberDomain( index)].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for ") ACE_TEXT("subscriber[ %d] in domain %d.\n"), index, this->config_.subscriberDomain( index) )); throw BadParticipantException (); } } this->subscriberParticipant_[ index] = ::DDS::DomainParticipant::_duplicate (this->participants_[ this->config_.subscriberDomain( index)].in()); } // // Establish DomainParticipants for the publication domains. // for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher participant in domain %d.\n"), this->config_.publisherDomain( index) )); ParticipantMap::iterator where = this->participants_.find( this->config_.publisherDomain( index)); if( where == this->participants_.end()) { this->participants_[ this->config_.publisherDomain( index)] = factory->create_participant( this->config_.publisherDomain( index), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->participants_[ this->config_.publisherDomain( index)].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for ") ACE_TEXT("publisher[ %d] in domain %d.\n"), index, this->config_.publisherDomain( index) )); throw BadParticipantException (); } } this->publisherParticipant_[ index] = ::DDS::DomainParticipant::_duplicate (this->participants_[ this->config_.publisherDomain( index)].in()); } // // Grab and install the transport implementations. // // We need to have a separate transport implementation for each // repository since the RepoId space will collide between them without // modification of the current implementation. // // Establish debug level. if( this->config_.verbose()) { TURN_ON_VERBOSE_DEBUG; } // // We have to extract the repository keys here since if we configured // the repositories and domains from a file, we do not have that // information available to us. Drat. // std::set< OpenDDS::DCPS::Service_Participant::RepoKey> keylist; for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { keylist.insert( TheServiceParticipant->domain_to_repo( this->config_.subscriberDomain( index))); } for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { keylist.insert( TheServiceParticipant->domain_to_repo( this->config_.publisherDomain( index))); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating transports for repositories.\n"))); ACE_UINT32 transportKey = 0; for( std::set< OpenDDS::DCPS::Service_Participant::RepoKey>::const_iterator current = keylist.begin(); current != keylist.end(); ++current, ++transportKey) { // Only create transports that need to be. if( false == TheTransportFactory->obtain( transportKey).is_nil()) { continue; } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating a SimpleTCP transport for repository: %d.\n"), *current )); this->transport_[ *current] = TheTransportFactory->create_transport_impl( transportKey, ACE_TEXT("SimpleTcp"), OpenDDS::DCPS::DONT_AUTO_CONFIG ); OpenDDS::DCPS::TransportConfiguration_rch reader_config = TheTransportFactory->create_configuration( transportKey, ACE_TEXT("SimpleTcp") ); // OpenDDS::DCPS::SimpleTcpConfiguration* reader_tcp_config // = static_cast <OpenDDS::DCPS::SimpleTcpConfiguration*>( reader_config.in() ); // // if( this->config_.transportAddressName().length() > 0) // { // ACE_INET_Addr reader_address( this->config_.transportAddressName().c_str()); // reader_tcp_config->local_address_ = reader_address; // reader_tcp_config->local_address_str_ = this->config_.transportAddressName(); // } // else use default address - OS assigned. if( this->transport_[ *current]->configure( reader_config.in()) != 0) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: TCP ") ACE_TEXT("failed to configure the transport.\n"))); throw BadTransportException (); } } // // Establish the listeners. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader listener for domain %d.\n"), this->config_.subscriberDomain( index) )); this->listener_[ index] = new ForwardingListenerImpl( TheServiceParticipant->domain_to_repo( this->config_.subscriberDomain( index) )); this->forwarder_[ index] = dynamic_cast<ForwardingListenerImpl*>(this->listener_[ index].in()); if (CORBA::is_nil (this->listener_[ index].in ())) { ACE_ERROR((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: failed to obtain listener for domain %d.\n"), this->config_.subscriberDomain( index) )); throw BadReaderListenerException (); } } // // Establish the Type Support for the data in each participant. (??) // for( ParticipantMap::const_iterator current = this->participants_.begin(); current != this->participants_.end(); ++current) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: Installing type %C support into domain %d.\n"), this->config_.typeName().c_str(), current->first )); if( 0 == CORBA::is_nil( current->second.in())) { ::Xyz::FooNoKeyTypeSupportImpl* subscriber_data = new ::Xyz::FooNoKeyTypeSupportImpl(); if(::DDS::RETCODE_OK != subscriber_data->register_type( current->second.in (), this->config_.typeName().c_str() ) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Unable to install type %C support for domain %d.\n"), this->config_.typeName().c_str(), current->first )); throw TestException (); } } } // // Establish the Subscriber Topics. // for( int index = 0; index < this->config_.readerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscription[ %d] topic: %C.\n"), index, this->config_.readerTopicName( index).c_str() )); this->readerTopic_[ index] = this->participants_[ this->config_.subscriberDomain( index)]->create_topic( this->config_.readerTopicName( index).c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->readerTopic_[ index].in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create topic %C for subscriber[ %d].\n"), this->config_.readerTopicName( index).c_str(), index )); throw BadTopicException (); } } // // Establish the Publisher Topics. // for( int index = 0; index < this->config_.writerTopicNameSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publication[ %d] topic: %C.\n"), index, this->config_.writerTopicName( index).c_str() )); this->writerTopic_[ index] = this->participants_[ this->config_.publisherDomain( index)]->create_topic( this->config_.writerTopicName( index).c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->writerTopic_[ index].in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create topic %C for publisher[ %d].\n"), this->config_.writerTopicName( index).c_str(), index )); throw BadTopicException (); } } // // Establish the Subscribers. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber[ %d].\n"), index )); this->subscriber_[ index] = this->participants_[ this->config_.subscriberDomain( index)]->create_subscriber( SUBSCRIBER_QOS_DEFAULT, ::DDS::SubscriberListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->subscriber_[ index].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_subscriber[ %d].\n"), index )); throw BadSubscriberException (); } // Attach the subscriber to the transport. OpenDDS::DCPS::SubscriberImpl* sub_impl = dynamic_cast<OpenDDS::DCPS::SubscriberImpl*>( this->subscriber_[ index].in () ); if (0 == sub_impl) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to obtain subscriber servant[ %d]\n"), index )); throw BadSubscriberException (); } OpenDDS::DCPS::AttachStatus attach_status; ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: attaching subscriber[ %d] to transport \n"), index )); attach_status = sub_impl->attach_transport( this->transport_[ TheServiceParticipant->domain_to_repo( this->config_.subscriberDomain( index)) ].in() ); if (attach_status != OpenDDS::DCPS::ATTACH_OK) { // We failed to attach to the transport for some reason. ACE_TString status_str; switch (attach_status) { case OpenDDS::DCPS::ATTACH_BAD_TRANSPORT: status_str = ACE_TEXT("ATTACH_BAD_TRANSPORT"); break; case OpenDDS::DCPS::ATTACH_ERROR: status_str = ACE_TEXT("ATTACH_ERROR"); break; case OpenDDS::DCPS::ATTACH_INCOMPATIBLE_QOS: status_str = ACE_TEXT("ATTACH_INCOMPATIBLE_QOS"); break; default: status_str = ACE_TEXT("Unknown Status"); break; } ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to attach to the transport. ") ACE_TEXT("AttachStatus == %s\n"), status_str.c_str())); throw BadTransportException (); } } // // Establish the Publishers. // for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher[ %d].\n"), index )); this->publisher_[ index] = this->participants_[ this->config_.publisherDomain( index)]->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->publisher_[ index].in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_publisher[ %d].\n"), index )); throw BadSubscriberException (); } // Attach the publisher to the transport. OpenDDS::DCPS::PublisherImpl* pub_impl = dynamic_cast<OpenDDS::DCPS::PublisherImpl*>( this->publisher_[ index].in () ); if (0 == pub_impl) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to obtain publisher servant[ %d]\n"), index )); throw BadSubscriberException (); } OpenDDS::DCPS::AttachStatus attach_status; ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: attaching publisher[ %d] to transport \n"), index )); attach_status = pub_impl->attach_transport( this->transport_[ TheServiceParticipant->domain_to_repo( this->config_.publisherDomain( index)) ].in() ); if (attach_status != OpenDDS::DCPS::ATTACH_OK) { // We failed to attach to the transport for some reason. ACE_TString status_str; switch (attach_status) { case OpenDDS::DCPS::ATTACH_BAD_TRANSPORT: status_str = ACE_TEXT("ATTACH_BAD_TRANSPORT"); break; case OpenDDS::DCPS::ATTACH_ERROR: status_str = ACE_TEXT("ATTACH_ERROR"); break; case OpenDDS::DCPS::ATTACH_INCOMPATIBLE_QOS: status_str = ACE_TEXT("ATTACH_INCOMPATIBLE_QOS"); break; default: status_str = ACE_TEXT("Unknown Status"); break; } ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: Failed to attach to the transport. ") ACE_TEXT("AttachStatus == %s\n"), status_str.c_str())); throw BadTransportException (); } } // // Establish and install the DataWriter. // for( int index = 0; index < this->config_.publisherDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating datawriter[ %d].\n"), index )); ::DDS::DataWriterListener_var listener ( new DataWriterListenerImpl( TheServiceParticipant->domain_to_repo( this->config_.publisherDomain( index) ))); // // Keep all data samples to allow us to establish connections in an // arbitrary order, with samples being buffered at the first writer // that has not yet had a subscription match. // ::DDS::DataWriterQos writerQos; this->publisher_[ index]->get_default_datawriter_qos( writerQos); writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; writerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; writerQos.reliability.max_blocking_time.sec = 0; writerQos.reliability.max_blocking_time.nanosec = 0; this->dataWriter_[ index] = this->publisher_[ index]->create_datawriter(this->writerTopic_[ index].in(), writerQos, listener.in(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if( CORBA::is_nil( this->dataWriter_[ index].in()) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create datawriter[ %d] failed.\n"), index )); throw BadWriterException (); } } for( unsigned int index = 1; index < this->forwarder_.size(); ++index) { // Pass the writer into the (previous) forwarder. this->forwarder_[ index - 1]->dataWriter( this->dataWriter_[ index].in()); } // The last forwarder does not. this->forwarder_[ this->forwarder_.size() - 1]->dataWriter( ::DDS::DataWriter::_nil() ); // // Establish and install the DataReader. This needs to be done after // the writer has been created and attached since it is possible (I // know, I've seen it happen!) that messages can be received and // forwarded between the time the reader is created and the writer is // created and attached to the forwarder if we do it the other way // round. // for( int index = 0; index < this->config_.subscriberDomainSize(); ++index) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader[ %d].\n"), index )); ::DDS::TopicDescription_var description = this->participants_[ this->config_.subscriberDomain( index)]->lookup_topicdescription( this->config_.readerTopicName( index).c_str() ); this->dataReader_[ index] = this->subscriber_[ index]->create_datareader( description.in(), DATAREADER_QOS_DEFAULT, this->listener_[ index].in (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->dataReader_[ index].in()) ) { ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create datareader[ %d] failed.\n"), index )); throw BadReaderException (); } } }
/** * @brief Construct a test system from the command line. */ TestSystem::TestSystem( int argc, ACE_TCHAR** argv, char** envp) : config_( argc, argv, envp) , subscriberParticipant_(0) , publisherParticipant_(0) , subscriber_(0) , publisher_(0) , readerTopic_(0) , writerTopic_(0) , dataReader_(0) , dataWriter_(0) , listener_(0) , transport_() { // Grab a local reference to the factory to ensure that we perform the // operations - they should not get optimized away! Note that this // passes the arguments to the ORB initialization first, then strips // the DCPS arguments. ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: initializing the service.%d\n"), this->config_.infoRepoIorSize())); ::DDS::DomainParticipantFactory_var factory = TheParticipantFactoryWithArgs( argc, argv); // We only need to do loading and binding if we receive InfoRepo IOR // values on the command line - otherwise this is done during // configuration file processing. if( this->config_.infoRepoIorSize() > 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: loading repository %C.\n"), OpenDDS::DCPS::Discovery::DEFAULT_REPO )); TheServiceParticipant->set_repo_ior( this->config_.infoRepoIor().c_str()); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding subscriber domain to repository %C.\n"), OpenDDS::DCPS::Discovery::DEFAULT_REPO )); TheServiceParticipant->set_repo_domain( this->config_.subscriberDomain(), OpenDDS::DCPS::Discovery::DEFAULT_REPO ); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: binding publisher domain to repository %C.\n"), OpenDDS::DCPS::Discovery::DEFAULT_REPO )); TheServiceParticipant->set_repo_domain( this->config_.publisherDomain(), OpenDDS::DCPS::Discovery::DEFAULT_REPO ); #if 1 TheServiceParticipant->monitor_factory_->initialize(); #endif } // // Establish a DomainParticipant for the subscription domain. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber participant in domain %d.\n"), this->config_.subscriberDomain() )); this->subscriberParticipant_ = factory->create_participant( this->config_.subscriberDomain(), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->subscriberParticipant_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for subscriber.\n"))); throw BadParticipantException (); } // // Establish a DomainParticipant for the publication domain. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher participant in domain %d.\n"), this->config_.publisherDomain() )); if( this->config_.publisherDomain() == this->config_.subscriberDomain()) { // // Just reference the same participant for both activities if they // are in the same domain. // this->publisherParticipant_ = ::DDS::DomainParticipant::_duplicate(this->subscriberParticipant_.in()); } else { this->publisherParticipant_ = factory->create_participant( this->config_.publisherDomain(), PARTICIPANT_QOS_DEFAULT, ::DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if (CORBA::is_nil (this->publisherParticipant_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_participant failed for publisher.\n"))); throw BadParticipantException (); } } // // Grab and install the transport implementation. // NOTE: Try to use a single transport first. This is something that // needs to be verified and documented. // // Establish debug level. if( this->config_.verbose()) { TURN_ON_VERBOSE_DEBUG; } // // Establish a listener to install into the DataReader. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader listener.\n"))); this->listener_ = new ForwardingListenerImpl(OpenDDS::DCPS::Discovery::DEFAULT_REPO); ForwardingListenerImpl* forwarder_servant = dynamic_cast<ForwardingListenerImpl*>(listener_.in()); if (CORBA::is_nil (this->listener_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: listener is nil.\n"))); throw BadReaderListenerException (); } // // Establish the Type Support for the data. // MJM: Do we need to have two distinct instantiations here? Or can we // share the servant across domains? // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscription type support for type %C.\n"), this->config_.typeName().c_str() )); ::Xyz::FooNoKeyTypeSupport_var subscriber_data = new ::Xyz::FooNoKeyTypeSupportImpl(); if(::DDS::RETCODE_OK != subscriber_data->register_type( this->subscriberParticipant_.in (), this->config_.typeName().c_str() ) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to register the subscriber FooNoKeyTypeSupport.\n"))); throw TestException (); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publication type support for type %C.\n"), this->config_.typeName().c_str() )); ::Xyz::FooNoKeyTypeSupport_var publisher_data = new ::Xyz::FooNoKeyTypeSupportImpl(); if(::DDS::RETCODE_OK != publisher_data->register_type( this->publisherParticipant_.in (), this->config_.typeName().c_str() ) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to register the publisher FooNoKeyTypeSupport.\n"))); throw TestException (); } // // Establish the Subscriber and Publisher Topics. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscription topic: %C.\n"), this->config_.readerTopicName().c_str() )); this->readerTopic_ = this->subscriberParticipant_->create_topic( this->config_.readerTopicName().c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->readerTopic_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_topic for subscriber.\n"))); throw BadTopicException (); } ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publication topic: %C.\n"), this->config_.writerTopicName().c_str() )); this->writerTopic_ = this->publisherParticipant_->create_topic( this->config_.writerTopicName().c_str(), this->config_.typeName().c_str(), TOPIC_QOS_DEFAULT, ::DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->readerTopic_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_topic for publisher.\n"))); throw BadTopicException (); } // // Establish the Subscriber. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating subscriber.\n"))); this->subscriber_ = this->subscriberParticipant_->create_subscriber( SUBSCRIBER_QOS_DEFAULT, ::DDS::SubscriberListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->subscriber_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_subscriber.\n"))); throw BadSubscriberException (); } // // Establish the Publisher. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating publisher.\n"))); this->publisher_ = this->publisherParticipant_->create_publisher( PUBLISHER_QOS_DEFAULT, ::DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (this->publisher_.in ())) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %T ERROR: Failed to create_publisher.\n"))); throw BadPublisherException (); } // // Establish and install the DataWriter. // ::DDS::DataWriterListener_var listener (new DataWriterListenerImpl(OpenDDS::DCPS::Discovery::DEFAULT_REPO)); // // Keep all data samples to allow us to establish connections in an // arbitrary order, with samples being buffered at the first writer // that has not yet had a subscription match. // ::DDS::DataWriterQos writerQos; this->publisher_->get_default_datawriter_qos( writerQos); writerQos.durability.kind = ::DDS::TRANSIENT_LOCAL_DURABILITY_QOS; writerQos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; writerQos.resource_limits.max_samples_per_instance = ::DDS::LENGTH_UNLIMITED; writerQos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; writerQos.reliability.max_blocking_time.sec = 0; writerQos.reliability.max_blocking_time.nanosec = 0; ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data writer.\n"))); this->dataWriter_ = this->publisher_->create_datawriter( this->writerTopic_.in(), writerQos, listener.in(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->dataWriter_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_datawriter failed.\n"))); throw BadWriterException (); } // Pass the writer into the forwarder. forwarder_servant->dataWriter( this->dataWriter_.in()); // // Establish and install the DataReader. This needs to be done after // the writer has been created and attached since it is possible (I // know, I've seen it happen!) that messages can be received and // forwarded between the time the reader is created and the writer is // created and attached to the forwarder if we do it the other way // round. // ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: looking up subscription topic.\n"))); ::DDS::TopicDescription_var description = this->subscriberParticipant_->lookup_topicdescription( this->config_.readerTopicName().c_str() ); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) %T INFO: creating data reader for topic: %C, type: %C.\n"), CORBA::String_var(description->get_name()).in(), CORBA::String_var(description->get_type_name()).in() )); this->dataReader_ = this->subscriber_->create_datareader( description.in(), DATAREADER_QOS_DEFAULT, this->listener_.in (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK ); if( CORBA::is_nil( this->dataReader_.in()) ) { ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) %T ERROR: create_datareader failed.\n"))); throw BadReaderException (); } }