INTRODUCTION
Overview
Download and Install
Quick Start
Documentation
Publications

NONFRAMEWORK CODE
Driver Interfaces
Drivers
Libraries
Utilities

FRAMEWORK CODE
Interfaces
Components
Libraries
Utilities

Full Software Listings

DEVELOPER
Tutorials
Examples
Dev Guide
Dashboard

PEOPLE
Contributors
Users

SourceForge.net Logo
Project
Download
Mailing lists

 

         

icestormutils.h

00001 
00002 
00003 /*
00004  * Orca-Robotics Project: Components for robotics
00005  *               http://orca-robotics.sf.net/
00006  * Copyright (c) 2004-2009 Alex Brooks, Alexei Makarenko, Tobias Kaupp
00007  *
00008  * This copy of Orca is licensed to you under the terms described in
00009  * the LICENSE file included in this distribution.
00010  *
00011  */
00012 
00013 #ifndef ORCAICE_ICESTORM_UTILITIES_H
00014 #define ORCAICE_ICESTORM_UTILITIES_H
00015 
00016 #include <IceStorm/IceStorm.h>
00017 
00018 #include <orcaice/context.h>
00019 #include <orcaice/exceptions.h>
00020 #include <orcaice/configutils.h>
00021 #include <orcaice/printutils.h>
00022 #include <orcaice/stringutils.h>
00023 
00024 namespace orcaice
00025 {
00030 
00054 template<class ConsumerProxyType>
00055 ConsumerProxyType
00056 createConsumerInterface( const Context  & context,
00057                          Ice::ObjectPtr & consumer )
00058 {
00059     // create servant and tell adapter about it (let it make up a globally unique name)
00060     // NOTE: addWithUUID() does not throw exceptions.
00061     try
00062     {
00063         Ice::ObjectPrx obj = context.adapter()->addWithUUID( consumer );
00064 
00065         // make a direct proxy
00066         Ice::ObjectPrx prx = context.adapter()->createDirectProxy( obj->ice_getIdentity() );
00067         return ConsumerProxyType::uncheckedCast( prx );
00068     }
00069     catch( const Ice::ObjectAdapterDeactivatedException &e )
00070     {
00071         std::stringstream ss;
00072         ss << "orcaice::Component: Failed to create consumer interface because the adapter is destroyed : " << e;
00073         bool localOnly = true;
00074         context.tracer().warning( ss.str(), 1, localOnly );
00075         throw orcaice::ComponentDeactivatingException( ERROR_INFO, ss.str() );
00076     }
00077 }
00078 
00079 // FUNCTIONS WITHOUT DOXYGEN TAGS ARE UTILITY FUNCTIONS
00080 // THEY ARE PUBLICLY AVAILABLE BUT ARE NOT ADVERTIZED THROUGH DOXYGEN
00081 
00082 /*
00083  * Behaves the same as the one above but connects to the topic manager
00084  * specified in the current properties.
00085  */
00086 IceStorm::TopicPrx connectToIceStormTopicPrx( const Context &,
00087                                               const std::string & topicName,
00088                                               bool createIfMissing=false );
00089 
00090 /*
00091  * Behaves the same as the one above but connects to the topic manager
00092  * specified in the communicator's properties.
00093  */
00094 IceStorm::TopicPrx connectToIceStormTopicPrx( const Ice::CommunicatorPtr & communicator,
00095                                               const std::string & topicName,
00096                                               bool createIfMissing=false );
00097 
00098 /*
00099  * Given the stingified proxy to topic manager and topic name, connect to the topic proxy.
00100  * If topic manager does not exist, throws Exception exception.
00101  */
00102 IceStorm::TopicPrx connectToIceStormTopicPrxWithManager( const Ice::CommunicatorPtr & communicator,
00103                                     const std::string & topicName,
00104                                     const std::string & topicManagerString,
00105                                     bool createIfMissing=false );
00106 
00107 /*
00108 Publisher is the IceStorm's consumer of information.
00109 So the publisher component (the provider of data) can push data into it.
00110 Remote calls!
00111 Connects to the topic and returns the topic's publisher.
00112  */
00113 Ice::ObjectPrx connectToIceStormTopicPublisherPrx( const Ice::CommunicatorPtr & communicator,
00114                                     const std::string & topicName );
00115 
00116 /*
00117 Local calls only.
00118  */
00119 Ice::ObjectPrx getIceStormTopicPublisherPrx( const IceStorm::TopicPrx & topic );
00120 
00136 template<class ConsumerProxyType>
00137 IceStorm::TopicPrx
00138 connectToTopicWithString( const Context     & context,
00139                           ConsumerProxyType & publisher,
00140                           const std::string & topicName,
00141                           bool localReportingOnly=false )
00142 {
00143     IceStorm::TopicPrx topicPrx;
00144 
00145     try {
00146         const bool createIfMissing = true;
00147         //
00148         // set the proxy to the topic
00149         //
00150         topicPrx = connectToIceStormTopicPrx( context.communicator(), topicName, createIfMissing );
00151 
00152         Ice::ObjectPrx obj = getIceStormTopicPublisherPrx( topicPrx );
00153         //
00154         // set the proxy to the publisher
00155         //
00156         publisher = ConsumerProxyType::uncheckedCast(obj);
00157     }
00158     //catch ( const gbxutilacfr::Exception & e ) {
00159         // we'll catch it here if the topic manager does not exist
00160     //}
00161     catch ( Ice::ConnectionRefusedException &e )
00162     {
00163         // Give some feedback as to why this isn't working
00164         std::stringstream ss; ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e;
00165         // not using status because we would need to add localReportingOnly option
00166         initTracerError( context, ss.str(), localReportingOnly );
00167         initTracerInfo( context, "hint: Is IceStorm running?", localReportingOnly );
00168         throw orcaice::NetworkException( ERROR_INFO, ss.str() );
00169     }
00170     catch( const Ice::LocalException &e )
00171     {
00172         std::stringstream ss;
00173         ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e;
00174         // not using status because we would need to add localReportingOnly option
00175         initTracerError( context, ss.str(), localReportingOnly );
00176         throw gbxutilacfr::Exception( ERROR_INFO, ss.str() );
00177     }
00178     catch ( Ice::Exception &e )
00179     {
00180         // Give some feedback as to why this isn't working
00181         std::stringstream ss; ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e;
00182         // not using status because we would need to add localReportingOnly option
00183         initTracerError( context, ss.str(), localReportingOnly );
00184         throw orcaice::NetworkException( ERROR_INFO, ss.str() );
00185     }
00186 
00187     return topicPrx;
00188 }
00189 
00198 template<class ConsumerProxyType>
00199 IceStorm::TopicPrx
00200 connectToTopicWithTag( const Context           & context,
00201                        ConsumerProxyType       & publisher,
00202                        const std::string       & interfaceTag,
00203                        const std::string       & subtopic="*",
00204                        bool localReportingOnly=false )
00205 {
00206     context.tracer().debug( "orcaice::connectToTopicWithTag() tag="+interfaceTag, 10 );
00207 
00208     // lookup the name of the interface in the config file and generate topic name.
00209     // this generates a standard topic name based on fully-qualified interface name.
00210     std::string topicName = orcaice::toString(
00211                     orcaice::getProvidedTopicWithTag( context, interfaceTag, subtopic ) );
00212 
00213     return connectToTopicWithString( context, publisher, topicName, localReportingOnly );
00214 }
00215 
00217 
00218 namespace detail {
00219 
00220     // Catches all exceptions.
00221     // Returns:
00222     // 0  : if re-connected
00223     // 1  : if failed to re-connect
00224     // -1 : if got CommunicatorDestroyedException
00225     template<class ConsumerPrxType>
00226     int
00227     tryReconnectToIceStorm( orcaice::Context   &context,
00228                             ConsumerPrxType    &publisherPrx,
00229                             IceStorm::TopicPrx &topicPrx,
00230                             const std::string  &topicName )
00231     {
00232         try {
00233             topicPrx = orcaice::connectToTopicWithString<ConsumerPrxType>
00234                 ( context, publisherPrx, topicName );
00235 
00236             std::string msg = "Re-connected to IceStorm topic "+topicName;
00237             context.tracer().info( msg );
00238 
00239             return 0;
00240         }
00241         catch ( const Ice::CommunicatorDestroyedException& )
00242         {
00243             return -1;
00244         }
00245         catch ( const Ice::Exception& e )
00246         {
00247             std::stringstream ss;
00248             ss << "Re-connection to IceStorm topic " << topicName << " failed:\n"
00249                << e.what();
00250             bool localOnly = true;
00251             context.tracer().warning( ss.str(), 1, localOnly );
00252             return 1;
00253         }
00254         catch ( ... )
00255         {
00256             std::string msg = "Re-connection to IceStorm topic "+topicName+" failed.";
00257             bool localOnly = true;
00258             context.tracer().warning( msg, 1, localOnly );
00259             return 1;
00260         }
00261     }
00262 
00263 }
00264 
00266 
00267 
00277 template<class ConsumerPrxType, class DataType>
00278 void tryPushToIceStormWithReconnect( orcaice::Context   &context,
00279                                 ConsumerPrxType    &publisherPrx,
00280                                 const DataType     &data,
00281                                 IceStorm::TopicPrx &topicPrx,
00282                                 const std::string  &topicName )
00283 {
00284     // check that communicator still exists
00285     if ( !context.communicator() ) {
00286         return;
00287     }
00288 
00289     // check that we are connected to the publisher
00290     if ( !publisherPrx ) {
00291         int reconnected = detail::tryReconnectToIceStorm(
00292                                 context, publisherPrx, topicPrx, topicName );
00293         bool localOnly = true;
00294         if ( reconnected==0 ) {
00295             context.tracer().info( "(while pushing data to IceStorm) connected to publisher.", 1, localOnly  );
00296         }
00297         else if ( reconnected>0 ) {
00298             context.tracer().info( "(while pushing data to IceStorm) failed to connect to publisher.", 1, localOnly  );
00299             return;
00300         }
00301         else {
00302             // CommunicatorDestroyedException
00303             // If we see this, we're obviously shutting down.  Don't bitch about anything.
00304             return;
00305         }
00306     }
00307 
00308     try {
00309         publisherPrx->setData( data );
00310     }
00311     catch ( Ice::CommunicatorDestroyedException & )
00312     {
00313         // If we see this, we're obviously shutting down.  Don't bitch about anything.
00314     }
00315     catch ( Ice::Exception &e )
00316     {
00317         // This could happen if IceStorm dies.
00318         // If we're running in an IceBox and the IceBox is shutting down,
00319         // this is expected (our co-located IceStorm is obviously going down).
00320         std::stringstream ss;
00321         ss << "(while pushing data to topic "<<topicName<<") 1st attempt failed: " << e.what();
00322         bool localOnly = true;
00323         context.tracer().warning( ss.str(), 1, localOnly  );
00324 
00325         // If IceStorm just re-started for some reason though, we want to try to re-connect
00326         int reconnected = detail::tryReconnectToIceStorm(
00327                                 context, publisherPrx, topicPrx, topicName );
00328         if ( reconnected==0 )
00329         {
00330             try {
00331                 // try again to push that last bit of info
00332                 publisherPrx->setData( data );
00333             }
00334             catch ( Ice::Exception &e )
00335             {
00336                 std::stringstream ss;
00337                 ss << "(while pushing data to topic "<<topicName<<") 2nd attempt failed: " << e.what();
00338                 bool localOnly = true;
00339                 context.tracer().warning( ss.str(), 1, localOnly  );
00340             }
00341         }
00342     }
00343 }
00344 
00346 
00347 } // namespace
00348 
00349 #endif
 

Webmaster: Tobias Kaupp (tobasco at users.sourceforge.net)


Generated for Orca Robotics by  doxygen 1.4.5