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

Generated on Fri Feb 12 20:05:23 2016 for OpenDDS by  doxygen 1.4.7