FederatorConfig.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #include "DcpsInfo_pch.h"
00009 #include "dds/DCPS/debug.h"
00010 #include "FederatorConfig.h"
00011 #include "FederatorC.h"
00012 #include "ace/Configuration.h"
00013 #include "ace/Configuration_Import_Export.h"
00014 #include "ace/Log_Priority.h"
00015 #include "ace/Log_Msg.h"
00016 #include "ace/OS_NS_stdlib.h"
00017 #include "ace/OS_NS_strings.h"
00018 #include "ace/OS_NS_sys_time.h"
00019 
00020 #include <algorithm>
00021 
00022 #if !defined (__ACE_INLINE__)
00023 # include "FederatorConfig.inl"
00024 #endif /* !__ACE_INLINE__ */
00025 
00026 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00027 
00028 namespace {
00029 
00030 // FederationDomain key value.
00031 const ACE_TCHAR FEDERATION_DOMAIN_KEY[] = ACE_TEXT("FederationDomain");
00032 
00033 // FederationId key value.
00034 const ACE_TCHAR FEDERATION_ID_KEY[] = ACE_TEXT("FederationId");
00035 
00036 // FederationId key value.
00037 const ACE_TCHAR FEDERATION_PORT_KEY[] = ACE_TEXT("FederationPort");
00038 
00039 /// Define an argument copying functor.
00040 class ArgCopier {
00041 public:
00042   /// Identify the action to take on the next argument.
00043   enum Action { COPY, FILENAME, IDVALUE, IORVALUE };
00044 
00045   /// Construct with a target pointer array.
00046   ArgCopier(OpenDDS::Federator::Config* config);
00047 
00048   /// The Functor function operator.
00049   void operator()(ACE_TCHAR* arg);
00050 
00051 private:
00052   /// The configuration object.
00053   OpenDDS::Federator::Config* config_;
00054 
00055   /// How to treat the next argument.
00056   Action action_;
00057 };
00058 
00059 ArgCopier::ArgCopier(OpenDDS::Federator::Config* config)
00060   : config_(config),
00061     action_(COPY)
00062 {
00063 
00064 } // namespace
00065 
00066 void
00067 ArgCopier::operator()(ACE_TCHAR* arg)
00068 {
00069   // Search for command line arguments to process rather than copy.
00070   if (::OpenDDS::Federator::Config::FEDERATOR_CONFIG_OPTION == arg) {
00071     // Configuration file option, filename value is next arg.
00072     this->action_ = FILENAME;
00073     return;
00074 
00075   } else if (::OpenDDS::Federator::Config::FEDERATOR_ID_OPTION == arg) {
00076     // Federation Id option, Id value is next arg.
00077     this->action_ = IDVALUE;
00078     return;
00079 
00080   } else if (::OpenDDS::Federator::Config::FEDERATE_WITH_OPTION == arg) {
00081     // Federate with option, IOR is next arg.
00082     this->action_ = IORVALUE;
00083     return;
00084   }
00085 
00086   // Process unrecognized arguments and all values.
00087   switch (this->action_) {
00088   case FILENAME:
00089     // Store the configuration file name.
00090     this->config_->configFile(arg);
00091     break;
00092 
00093   case IDVALUE:
00094     // Capture the federation Id.
00095     this->config_->federationId().id(ACE_OS::atoi(arg));
00096     break;
00097 
00098   case IORVALUE:
00099     // Capture the IOR to federate with.
00100     this->config_->federateIor(arg);
00101     break;
00102 
00103   case COPY:
00104     // Copy other args verbatim.
00105     this->config_->addArg(arg);
00106     break;
00107   }
00108 
00109   this->action_ = COPY;
00110 }
00111 
00112 int random_id()
00113 {
00114   ACE_UINT64 msec;
00115   ACE_OS::gettimeofday().msec(msec);
00116   ACE_OS::srand((unsigned int)msec);
00117   const int r = ACE_OS::rand();
00118   return r;
00119 }
00120 
00121 void hash_endpoint(::CORBA::Long& hash, const char* const endpoint, const size_t len)
00122 {
00123   std::string toprint(endpoint, len);
00124   if (len > 0)
00125   {
00126     for (size_t i = 0; i < len; i++)
00127     {
00128       hash = 31 * hash + endpoint[i];
00129     }
00130   }
00131 }
00132 
00133 #if defined (ACE_USES_WCHAR)
00134 void hash_endpoint(::CORBA::Long& hash, const wchar_t* const endpoint, const size_t len)
00135 {
00136   // treat the wchar string as a double length string
00137   hash_endpoint(hash, reinterpret_cast<const char*>(endpoint), len * 2);
00138 }
00139 #endif
00140 
00141 void hash_endpoints(::CORBA::Long& hash, const ACE_TCHAR* const endpoints_str)
00142 {
00143   const ACE_TCHAR* delim = ACE_TEXT(";");
00144   const size_t len = ACE_OS::strlen(endpoints_str);
00145   const ACE_TCHAR* curr = endpoints_str;
00146   while (curr < endpoints_str + len) {
00147     const ACE_TCHAR* next = ACE_OS::strstr(curr, delim);
00148     if (next == 0)
00149       next = endpoints_str + len;
00150     hash_endpoint(hash, curr, (next - curr));
00151     curr = next + 1;
00152   }
00153 }
00154 
00155 ::CORBA::Long hash_endpoints(int argc, ACE_TCHAR** argv)
00156 {
00157   ::CORBA::Long hash = 0;
00158   bool found = false;
00159   for (int i = 0; i < argc - 1; ++i) {
00160     if (ACE_OS::strncasecmp(argv[i], ACE_TEXT("-ORB"), ACE_OS::strlen(ACE_TEXT("-ORB"))) == 0 &&
00161         (ACE_OS::strcasecmp(ACE_TEXT("-ORBEndpoint"), argv[i]) == 0 ||
00162          ACE_OS::strcasecmp(ACE_TEXT("-ORBListenEndpoints"), argv[i]) == 0 ||
00163          ACE_OS::strcasecmp(ACE_TEXT("-ORBLaneEndpoint"), argv[i]) == 0 ||
00164          ACE_OS::strcasecmp(ACE_TEXT("-ORBLaneListenEndpoints"), argv[i]) == 0)) {
00165       const ACE_TCHAR* enpoints = argv[++i];
00166       hash_endpoints(hash, enpoints);
00167       found = true;
00168     }
00169   }
00170   if (!found) {
00171     hash = random_id();
00172   }
00173   return hash;
00174 }
00175 
00176 } // End of anonymous namespace
00177 
00178 namespace OpenDDS {
00179 namespace Federator {
00180 
00181 const tstring
00182 Config::FEDERATOR_CONFIG_OPTION(ACE_TEXT("-FederatorConfig"));
00183 
00184 const tstring
00185 Config::FEDERATOR_ID_OPTION(ACE_TEXT("-FederationId"));
00186 
00187 const tstring
00188 Config::FEDERATE_WITH_OPTION(ACE_TEXT("-FederateWith"));
00189 
00190 Config::Config(int argc, ACE_TCHAR** argv)
00191   : argc_(0),
00192     federationId_(hash_endpoints(argc, argv)),
00193     federationDomain_(DEFAULT_FEDERATIONDOMAIN),
00194     federationPort_(-1)
00195 {
00196   if (::OpenDDS::DCPS::DCPS_debug_level > 0) {
00197     ACE_DEBUG((LM_DEBUG,
00198                ACE_TEXT("(%P|%t) INFO: Federator::Config::Config()\n")));
00199   }
00200 
00201   // Setup the internal storage.
00202   this->argv_ = new ACE_TCHAR*[argc + 1](); // argv_[argc] == 0
00203 
00204   // Process the federation arguments.  Copy the uninteresting arguments verbatim.
00205   ArgCopier argCopier(this);
00206   std::for_each(&argv[0], &argv[ argc], argCopier);
00207 
00208   // Read and process any configuration file.
00209   this->processFile();
00210 }
00211 
00212 Config::~Config()
00213 {
00214   if (::OpenDDS::DCPS::DCPS_debug_level > 0) {
00215     ACE_DEBUG((LM_DEBUG,
00216                ACE_TEXT("(%P|%t) INFO: Federator::Config::~FederatorConfig()\n")));
00217   }
00218 
00219   // We prwn this
00220   delete [] this->argv_;
00221 }
00222 
00223 void
00224 Config::processFile()
00225 {
00226   if (::OpenDDS::DCPS::DCPS_debug_level > 0) {
00227     ACE_DEBUG((LM_DEBUG,
00228                ACE_TEXT("(%P|%t) INFO: Federator::Config::process()\n")));
00229   }
00230 
00231   if (this->configFile_.empty()) {
00232     // No filename, no processing.
00233     return;
00234   }
00235 
00236   // Grab a spot to stick the configuration.
00237   ACE_Configuration_Heap heap;
00238 
00239   if (0 != heap.open()) {
00240     ACE_ERROR((LM_ERROR,
00241                ACE_TEXT("(%P|%t) ERROR: Federator::Config::process - ")
00242                ACE_TEXT("unable to open configuration heap.\n")));
00243     return;
00244   }
00245 
00246   // Import the file into our shiny new spot.
00247   ACE_Ini_ImpExp import(heap);
00248 
00249   if (0 != import.import_config(this->configFile_.c_str())) {
00250     ACE_ERROR((LM_ERROR,
00251                ACE_TEXT("(%P|%t) ERROR: Federator::Config::process - ")
00252                ACE_TEXT("unable to import configuration file.\n")));
00253     return;
00254   }
00255 
00256   // Configuration file format:
00257   //
00258   //   FederationDomain = <number>                       (REQUIRED)
00259   //   FederationId     = <number>                       (REQUIRED)
00260   //   FederationPort   = <number>                       (REQUIRED)
00261   //
00262 
00263   // Grab the common configuration settings.
00264   const ACE_Configuration_Section_Key &root = heap.root_section();
00265 
00266   // Federation Domain value - REQUIRED
00267   ACE_TString federationDomainString;
00268 
00269   if (0 != heap.get_string_value(root, FEDERATION_DOMAIN_KEY, federationDomainString)) {
00270     ACE_ERROR((LM_ERROR,
00271                ACE_TEXT("(%P|%t) ERROR: Federator::Config::process - ")
00272                ACE_TEXT("Unable to obtain value for FederationDomain in root section\n")));
00273     return;
00274   }
00275 
00276   // Convert to numeric repository key value.
00277   this->federationDomain_ = ACE_OS::atoi(federationDomainString.c_str());
00278 
00279   if (::OpenDDS::DCPS::DCPS_debug_level > 0) {
00280     ACE_DEBUG((LM_DEBUG,
00281                ACE_TEXT("(%P|%t)   FederationDomain == %d\n"),
00282                this->federationDomain_));
00283   }
00284 
00285   // Federation Id value - REQUIRED
00286   ACE_TString federationIdString;
00287 
00288   if (0 != heap.get_string_value(root, FEDERATION_ID_KEY, federationIdString)) {
00289     ACE_ERROR((LM_ERROR,
00290                ACE_TEXT("(%P|%t) ERROR: Federator::Config::process - ")
00291                ACE_TEXT("Unable to obtain value for FederationId in root section\n")));
00292     return;
00293   }
00294 
00295   // Convert to numeric repository key value.
00296   RepoKey idValue = ACE_OS::atoi(federationIdString.c_str());
00297 
00298   // Allow the command line to override the file value.
00299   if (this->federationId_.overridden()) {
00300     ACE_DEBUG((LM_DEBUG,
00301                ACE_TEXT("(%P|%t)   FederationId == %d from file ")
00302                ACE_TEXT("overridden by value %d from command line.\n"),
00303                idValue,
00304                this->federationId_.id()));
00305 
00306   } else {
00307     this->federationId_.id(idValue);
00308 
00309     if (::OpenDDS::DCPS::DCPS_debug_level > 0) {
00310       ACE_DEBUG((LM_DEBUG,
00311                  ACE_TEXT("(%P|%t)   FederationId == %d\n"),
00312                  this->federationId_.id()));
00313     }
00314   }
00315 
00316   // Federation port value - REQUIRED
00317   ACE_TString federationPortString;
00318 
00319   if (0 != heap.get_string_value(root, FEDERATION_PORT_KEY, federationPortString)) {
00320     ACE_ERROR((LM_ERROR,
00321                ACE_TEXT("(%P|%t) ERROR: Federator::Config::process - ")
00322                ACE_TEXT("Unable to obtain value for FederationPort in root section\n")));
00323     return;
00324   }
00325 
00326   // Convert to numeric repository key value.
00327   this->federationPort_ = ACE_OS::atoi(federationPortString.c_str());
00328 
00329   if (::OpenDDS::DCPS::DCPS_debug_level > 0) {
00330     ACE_DEBUG((LM_DEBUG,
00331                ACE_TEXT("(%P|%t)   FederationPort == %d\n"),
00332                this->federationPort_));
00333   }
00334 }
00335 
00336 } // namespace Federator
00337 } // namespace OpenDDS
00338 
00339 OPENDDS_END_VERSIONED_NAMESPACE_DECL
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1