orca-robotics


INTRODUCTION
Overview
Download and Install
Quick Start
Documentation
Publications

REPOSITORY
Interfaces
Components
Libraries
Utilities
Software Map

DEVELOPER
Tutorials
Examples
Dev Guide
Dashboard
Wiki
login/pass: orca/orca

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-2008 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 <Ice/Ice.h>
00017 #include <IceStorm/IceStorm.h>
00018 
00019 #include <orcaice/context.h>
00020 #include <orcaice/exceptions.h>
00021 #include <orcaice/configutils.h>
00022 #include <orcaice/printutils.h>
00023 #include <orcaice/stringutils.h>
00024 
00025 namespace orcaice
00026 {
00031 
00052 template<class ConsumerProxyType>
00053 ConsumerProxyType
00054 createConsumerInterface( const Context  & context,
00055                          Ice::ObjectPtr & consumer )
00056 {
00057     // create servant and tell adapter about it (let it make up a globally unique name)
00058     // NOTE: addWithUUID() does not throw exceptions.
00059     try
00060     {
00061         Ice::ObjectPrx obj = context.adapter()->addWithUUID( consumer );
00062 
00063         // make a direct proxy
00064         Ice::ObjectPrx prx = context.adapter()->createDirectProxy( obj->ice_getIdentity() );
00065         return ConsumerProxyType::uncheckedCast( prx );
00066     }
00067     catch( const Ice::ObjectAdapterDeactivatedException &e )
00068     {
00069         std::stringstream ss;
00070         ss << "orcaice::Component: Failed to create consumer interface because the adapter is destroyed : " << e;
00071         bool localOnly = true;
00072         context.tracer().warning( ss.str(), 1, localOnly );
00073         throw orcaice::ComponentDeactivatingException( ERROR_INFO, ss.str() );
00074     }
00075 }
00076 
00077 // FUNCTIONS WITHOUT DOXYGEN TAGS ARE UTILITY FUNCTIONS
00078 // THEY ARE PUBLICLY AVAILABLE BUT ARE NOT ADVERTIZED THROUGH DOXYGEN
00079 
00080 /*
00081  * Behaves the same as the one above but connects to the topic manager
00082  * specified in the current properties.
00083  */
00084 IceStorm::TopicPrx connectToIceStormTopicPrx( const Context &,
00085                                               const std::string & topicName,
00086                                               bool createIfMissing=false );
00087 
00088 /*
00089  * Behaves the same as the one above but connects to the topic manager
00090  * specified in the communicator's properties.
00091  */
00092 IceStorm::TopicPrx connectToIceStormTopicPrx( const Ice::CommunicatorPtr & communicator,
00093                                               const std::string & topicName,
00094                                               bool createIfMissing=false );
00095 
00096 /*
00097  * Given the stingified proxy to topic manager and topic name, connect to the topic proxy.
00098  * If topic manager does not exist, throws Exception exception.
00099  */
00100 IceStorm::TopicPrx connectToIceStormTopicPrxWithManager( const Ice::CommunicatorPtr & communicator,
00101                                     const std::string & topicName,
00102                                     const std::string & topicManagerString,
00103                                     bool createIfMissing=false );
00104 
00105 /*
00106  * Publisher is used from the provider end. It is the consumer of information.
00107  * So you can push data into it.
00108  */
00109 Ice::ObjectPrx connectToIceStormTopicPublisherPrx( const Ice::CommunicatorPtr & communicator,
00110                                     const std::string & topicName );
00111 
00112 /*
00113  * Behaves like the one above.
00114  */
00115 Ice::ObjectPrx connectToIceStormTopicPublisherPrx( const IceStorm::TopicPrx & topic );
00116 
00117 
00126 template<class ConsumerProxyType>
00127 IceStorm::TopicPrx
00128 connectToTopicWithTag( const Context           & context,
00129                        ConsumerProxyType       & publisher,
00130                        const std::string       & interfaceTag,
00131                        const std::string       & subtopic="*" )
00132 {
00133     context.tracer().debug( "orcaice::connectToTopicWithTag() tag="+interfaceTag, 10 );
00134 
00135     // lookup the name of the interface in the config file and generate topic name.
00136     // this generates a standard topic name based on fully-qualified interface name.
00137     std::string topicName = orcaice::toString(
00138                     orcaice::getProvidedTopicWithTag( context, interfaceTag, subtopic ) );
00139 
00140     // do the conversion to string by hand, to cut dependency on libOrcaObj
00141     // see <orcaobj/stringutils.cpp>
00142 //     orca::FQTopicName name = orcaice::getProvidedTopicWithTag( context, interfaceTag, subtopic );
00143 //     std::string topicName =  name.iface + "/" + name.topic + "@" + name.platform + "/" + name.component;
00144 
00145     return connectToTopicWithString( context, publisher, topicName );
00146 }
00147 
00159 template<class ConsumerProxyType>
00160 IceStorm::TopicPrx
00161 connectToTopicWithString( const Context     & context,
00162                           ConsumerProxyType & publisher,
00163                           const std::string & topicName )
00164 {
00165     IceStorm::TopicPrx topicPrx;
00166 
00167     try {
00168         const bool createIfMissing = true;
00169         //
00170         // set the proxy to the topic
00171         //
00172         topicPrx = connectToIceStormTopicPrx( context.communicator(), topicName, createIfMissing );
00173 
00174         Ice::ObjectPrx obj = connectToIceStormTopicPublisherPrx( topicPrx );
00175         //
00176         // set the proxy to the publisher
00177         //
00178         publisher = ConsumerProxyType::uncheckedCast(obj);
00179     }
00180     //catch ( const gbxutilacfr::Exception & e ) {
00181         // we'll catch it here if the topic manager does not exist
00182     //}
00183     catch ( Ice::ConnectionRefusedException &e )
00184     {
00185         // Give some feedback as to why this isn't working
00186         std::stringstream ss; ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e;
00187         bool localOnly = true;
00188         initTracerError( context, ss.str(), 2, localOnly );
00189         initTracerInfo( context, "hint: Is IceStorm running?", 10, localOnly );
00190         throw orcaice::NetworkException( ERROR_INFO, ss.str() );
00191     }
00192     catch( const Ice::LocalException &e )
00193     {
00194         std::stringstream ss;
00195         ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e;
00196         bool localOnly = true;
00197         initTracerError( context, ss.str(), 2, localOnly );
00198         throw gbxutilacfr::Exception( ERROR_INFO, ss.str() );
00199     }
00200     catch ( Ice::Exception &e )
00201     {
00202         // Give some feedback as to why this isn't working
00203         std::stringstream ss; ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e;
00204         bool localOnly = true;
00205         initTracerError( context, ss.str(), 2, localOnly );
00206         throw orcaice::NetworkException( ERROR_INFO, ss.str() );
00207     }
00208 
00209     return topicPrx;
00210 }
00211 
00213 
00214 namespace detail {
00215 
00216     // Catches all exceptions.
00217     // Returns: 
00218     // 0  : if re-connected
00219     // 1  : if failed to re-connect
00220     // -1 : if got CommunicatorDestroyedException
00221     template<class ConsumerPrxType>
00222     int
00223     tryReconnectToIceStorm( orcaice::Context   &context,
00224                             ConsumerPrxType    &publisherPrx,
00225                             IceStorm::TopicPrx &topicPrx,
00226                             const std::string  &topicName )
00227     {
00228         try {
00229             topicPrx = orcaice::connectToTopicWithString<ConsumerPrxType>
00230                 ( context, publisherPrx, topicName );
00231 
00232             std::string msg = "Re-connected to IceStorm topic "+topicName;
00233             context.tracer().info( msg );
00234 
00235             return 0;
00236         }
00237         catch ( const Ice::CommunicatorDestroyedException& )
00238         {
00239             return -1;
00240         }
00241         catch ( ... )
00242         {
00243             std::string msg = "Re-connection to IceStorm topic "+topicName+" failed.";
00244             bool localOnly = true;
00245             context.tracer().info( msg, 1, localOnly );
00246             return 1;
00247         }
00248     }
00249 
00250 }
00251 
00253 
00254 
00264 template<class ConsumerPrxType, class DataType>
00265 void tryPushToIceStormWithReconnect( orcaice::Context   &context,
00266                                 ConsumerPrxType    &publisherPrx,
00267                                 const DataType     &data,
00268                                 IceStorm::TopicPrx &topicPrx,
00269                                 const std::string  &topicName )
00270 {
00271     // check that communicator still exists
00272     if ( !context.communicator() ) {
00273         return;
00274     }
00275 
00276     // check that we are connected to the publisher
00277     if ( !publisherPrx ) {
00278         int reconnected = detail::tryReconnectToIceStorm( 
00279                                 context, publisherPrx, topicPrx, topicName );
00280         bool localOnly = true;
00281         if ( reconnected==0 ) {
00282             context.tracer().info( "(while pushing data to IceStorm) connected to publisher.", 1, localOnly  );
00283         }
00284         else if ( reconnected>0 ) {
00285             context.tracer().info( "(while pushing data to IceStorm) failed to connect to publisher.", 1, localOnly  );
00286             return;
00287         }
00288         else {
00289             // CommunicatorDestroyedException
00290             // If we see this, we're obviously shutting down.  Don't bitch about anything.
00291             return;
00292         }
00293     }
00294 
00295     try {
00296         publisherPrx->setData( data );
00297     }
00298     catch ( Ice::CommunicatorDestroyedException & )
00299     {
00300         // If we see this, we're obviously shutting down.  Don't bitch about anything.
00301     }
00302     catch ( Ice::Exception &e )
00303     {
00304         // This could happen if IceStorm dies.
00305         // If we're running in an IceBox and the IceBox is shutting down, 
00306         // this is expected (our co-located IceStorm is obviously going down).
00307         std::stringstream ss;
00308         ss << "(while pushing data to topic "<<topicName<<") 1st attempt failed: " << e.what();
00309         bool localOnly = true;
00310         context.tracer().warning( ss.str(), 1, localOnly  );
00311 
00312         // If IceStorm just re-started for some reason though, we want to try to re-connect
00313         int reconnected = detail::tryReconnectToIceStorm( 
00314                                 context, publisherPrx, topicPrx, topicName );
00315         if ( reconnected==0 )
00316         {
00317             try {
00318                 // try again to push that last bit of info
00319                 publisherPrx->setData( data );
00320             }
00321             catch ( Ice::Exception &e )
00322             {
00323                 std::stringstream ss;
00324                 ss << "(while pushing data to topic "<<topicName<<") 2nd attempt failed: " << e.what();
00325                 bool localOnly = true;
00326                 context.tracer().warning( ss.str(), 1, localOnly  );
00327             }
00328         }
00329     }
00330 }
00331 
00333 
00334 } // namespace
00335 
00336 #endif
 

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


Generated for Orca Robotics by  doxygen 1.4.5