Back to index

nordugrid-arc-nox  1.1.0~rc6
InfoRegister.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <unistd.h>
00006 
00007 #include <arc/Thread.h>
00008 #include <arc/URL.h>
00009 #include <arc/message/PayloadSOAP.h>
00010 #include <arc/client/ClientInterface.h>
00011 #include <arc/StringConv.h>
00012 #include "InfoRegister.h"
00013 #ifdef WIN32
00014 #include <arc/win32.h>
00015 #endif
00016 
00017 namespace Arc {
00018 
00019 static Logger logger_(Logger::rootLogger, "InfoSys");
00020 
00021 static void reg_thread(void *data) {
00022     InfoRegistrar *self = (InfoRegistrar *)data;
00023     { // Very important!!!: Delete this block imediately!!!
00024         // Sleep and exit if interrupted by request to exit
00025         unsigned int sleep_time = 15; //seconds
00026         logger_.msg(VERBOSE, "InfoRegistrar thread waiting %d seconds for the all Registers elements creation.", sleep_time);
00027         sleep(sleep_time);
00028     }
00029     self->registration();
00030 }
00031 
00032 // -------------------------------------------------------------------
00033 
00034 InfoRegister::InfoRegister(XMLNode &cfg, Service *service):reg_period_(0),service_(service) {
00035     ns_["isis"] = ISIS_NAMESPACE;
00036     ns_["glue2"] = GLUE2_D42_NAMESPACE;
00037     ns_["register"] = REGISTRATION_NAMESPACE;
00038 
00039     // parse config
00040     std::string s_reg_period = (std::string)cfg["InfoRegister"]["Period"];
00041     if (!s_reg_period.empty()) {
00042         Period p(s_reg_period);
00043         reg_period_ = p.GetPeriod();
00044         if (reg_period_ < 120)
00045             reg_period_ = 120;
00046     } else {
00047         reg_period_ = -1;
00048     }
00049     std::string s_serviceid = (std::string)cfg["InfoRegister"]["ServiceID"];
00050     if (!s_serviceid.empty()) {
00051         serviceid = s_serviceid;
00052     }
00053     if ((bool)cfg["InfoRegister"]["Endpoint"])
00054         endpoint = (std::string)cfg["InfoRegister"]["Endpoint"];
00055     if ((bool)cfg["InfoRegister"]["Expiration"])
00056         expiration = (std::string)cfg["InfoRegister"]["Expiration"];
00057 
00058     //VERBOSE//
00059     std::string configuration_string;
00060     XMLNode temp;
00061     cfg.New(temp);
00062     temp.GetDoc(configuration_string, true);
00063     logger_.msg(VERBOSE, "InfoRegister created with config:\n%s", configuration_string);
00064 
00065     // Add service to registration list. Optionally only for
00066     // registration through specific registrants.
00067     std::list<std::string> ids;
00068     for(XMLNode r = cfg["InfoRegister"]["Registrar"];(bool)r;++r) {
00069       std::string id = (std::string) r["URL"];
00070       if(!id.empty()) ids.push_back(id);
00071       else logger_.msg(WARNING, "Discarding Registrar because the \"URL\" element is missing or empty.");
00072     };
00073     InfoRegisterContainer::Instance().addService(this,ids,cfg);
00074 }
00075 
00076 InfoRegister::~InfoRegister(void) {
00077     // This element is supposed to be destroyed with service.
00078     // Hence service should not be restered anymore.
00079     // TODO: initiate un-register of service
00080     InfoRegisterContainer::Instance().removeService(this);
00081 }
00082 
00083 // -------------------------------------------------------------------
00084 
00085 InfoRegisterContainer* InfoRegisterContainer::instance_ = NULL;
00086 
00087 InfoRegisterContainer& InfoRegisterContainer::Instance(void) {
00088   if(!instance_) instance_ = new InfoRegisterContainer;
00089   return *instance_;
00090 }
00091 
00092 InfoRegisterContainer::InfoRegisterContainer(void) {
00093 }
00094 
00095 InfoRegisterContainer::~InfoRegisterContainer(void) {
00096     Glib::Mutex::Lock lock(lock_);
00097     for(std::list<InfoRegistrar*>::iterator r = regr_.begin();
00098                               r != regr_.end();++r) {
00099         delete (*r);
00100     };
00101 }
00102 
00103 InfoRegistrar *InfoRegisterContainer::addRegistrar(XMLNode node) {
00104     //Glib::Mutex::Lock lock(lock_);
00105     InfoRegistrar* r = new InfoRegistrar(node);
00106     if(!(*r)) {
00107          delete r;
00108          return NULL;
00109     }
00110     regr_.push_back(r);
00111     CreateThreadFunction(&reg_thread, r);
00112     return r;
00113 }
00114 
00115 void InfoRegisterContainer::addService(InfoRegister* reg,const std::list<std::string>& ids,XMLNode cfg) {
00116     // Add to registrars
00117     Glib::Mutex::Lock lock(lock_);
00118     for(std::list<std::string>::const_iterator i = ids.begin(); i != ids.end();++i) {
00119         bool id_found = false;
00120         for(std::list<InfoRegistrar*>::iterator r = regr_.begin(); r != regr_.end();++r) {
00121             if((*i) == (*r)->id()) {
00122                 logger_.msg(VERBOSE, "InfoRegistrar id \"%s\" has been found.", (*i));
00123                 (*r)->addService(reg, cfg);
00124                 id_found = true;
00125             }
00126         }
00127         if (!id_found) {
00128             // id appears at first time - InfoRegistrar need to be created
00129             logger_.msg(VERBOSE, "InfoRegistrar id \"%s\" was not found. New registrar created", (*i));
00130             for(XMLNode node = cfg["InfoRegister"]["Registrar"];(bool)node;++node) {
00131                 if ((*i) == (std::string)node["URL"]) {
00132                     InfoRegistrar *r = addRegistrar(node);
00133                     if (r != NULL) r->addService(reg, cfg);
00134                 }
00135             }
00136         }
00137     }
00138 }
00139 
00140 void InfoRegisterContainer::removeService(InfoRegister* reg) {
00141     // If this method is called that means service is most probably
00142     // being deleted.
00143     Glib::Mutex::Lock lock(lock_);
00144     for(std::list<InfoRegistrar*>::iterator r = regr_.begin();
00145                               r != regr_.end();++r) {
00146             (*r)->removeService(reg);
00147     };
00148 }
00149 
00150 // -------------------------------------------------------------------
00151 
00152 InfoRegistrar::InfoRegistrar(XMLNode cfg):stretch_window("PT20S") {
00153     id_=(std::string)cfg["URL"];
00154 
00155     if ((bool)cfg["Retry"]) {
00156         if (!((std::string)cfg["Retry"]).empty()) {
00157             if(EOF == sscanf(((std::string)cfg["Retry"]).c_str(), "%d", &retry) || retry < 0)
00158             {
00159                 logger_.msg(ERROR, "Configuration error. Retry: \"%s\" is not a valid value. Default value will be used.",(std::string)cfg["Retry"]);
00160                 retry = 5;
00161             }
00162         } else retry = 5;
00163     } else retry = 5;
00164 
00165     logger_.msg(VERBOSE, "Retry: %d", retry);
00166 
00167     // Parsing security attributes
00168     key_ = (std::string)cfg["KeyPath"];
00169     cert_ = (std::string)cfg["CertificatePath"];
00170     proxy_ = (std::string)cfg["ProxyPath"];
00171     cadir_ = (std::string)cfg["CACertificatesDir"];
00172     cafile_ = (std::string)cfg["CACertificatePath"];
00173 
00174     logger_.msg(VERBOSE, "Key: %s, cert: %s", key_, cert_);
00175 
00176     initISIS(cfg);
00177 
00178     time_t rawtime;
00179     time ( &rawtime );  //current time
00180     gmtime ( &rawtime );
00181     Time ctime(rawtime);
00182     creation_time = ctime;
00183 }
00184 
00185 bool InfoRegistrar::addService(InfoRegister* reg, XMLNode& cfg) {
00186     if ( bool(cfg["NoRegister"]) || !bool(cfg["InfoRegister"])){
00187        logger_.msg(VERBOSE, "The service won't be registered.");
00188        return true;
00189     }
00190 
00191     if (!(bool)cfg["InfoRegister"]["Period"] ) {
00192        logger_.msg(ERROR, "Configuration error. Missing mandatory \"Period\" element.");
00193        return false;
00194     }
00195 
00196     if (!(bool)cfg["InfoRegister"]["Endpoint"] ) {
00197        logger_.msg(ERROR, "Configuration error. Missing mandatory \"Endpoint\" element.");
00198        return false;
00199     }
00200 
00201     if (!(bool)cfg["InfoRegister"]["Expiration"] ) {
00202        logger_.msg(ERROR, "Configuration error. Missing mandatory \"Expiration\" element.");
00203        return false;
00204     }
00205     Glib::Mutex::Lock lock(lock_);
00206     for(std::list<Register_Info_Type>::iterator r = reg_.begin();
00207                                            r!=reg_.end();++r) {
00208         if(reg == r->p_register) {
00209             logger_.msg(VERBOSE, "Service was already registered to the InfoRegistrar connecting to infosys %s.", myISIS.url);
00210             return false;
00211         }
00212     }
00213     Register_Info_Type reg_info;
00214     reg_info.p_register = reg;
00215 
00216     std::string current_serviceid = reg->getServiceID();
00217     std::string current_expiration = reg->getExpiration();
00218     std::string current_endpoint = reg->getEndpoint();
00219     Period period(reg->getPeriod());
00220     for(XMLNode node = cfg["InfoRegister"]["Registrar"];(bool)node;++node) {
00221         if ( (std::string)node["URL"] == id_ ) {
00222             if (! ((std::string)node["Period"]).empty() ) {
00223                 Period current_period((std::string)node["Period"]);
00224                 period = current_period;
00225             }
00226             if (! ((std::string)node["ServiceID"]).empty() ) {
00227                 current_serviceid = (std::string)node["ServiceID"];
00228             }
00229             if (! ((std::string)node["Endpoint"]).empty() ) {
00230                 current_endpoint = (std::string)node["Endpoint"];
00231             }
00232             if (! ((std::string)node["Expiration"]).empty() ) {
00233                 current_expiration = (std::string)node["Expiration"];
00234             }
00235        }
00236     }
00237 
00238     reg_info.period = period;
00239     reg_info.serviceid = current_serviceid;
00240     reg_info.expiration = current_expiration;
00241     reg_info.endpoint = current_endpoint;
00242 
00243     reg_info.next_registration = creation_time.GetTime();
00244     reg_.push_back(reg_info);
00245     logger_.msg(VERBOSE, "Service is successfully added to the InfoRegistrar connecting to infosys %s.", myISIS.url);
00246     return true;
00247 }
00248 
00249 bool InfoRegistrar::removeService(InfoRegister* reg) {
00250     Glib::Mutex::Lock lock(lock_);
00251     for(std::list<Register_Info_Type>::iterator r = reg_.begin();
00252                                            r!=reg_.end();++r) {
00253         if(reg == r->p_register) {
00254 
00255             NS reg_ns;
00256             reg_ns["glue2"] = GLUE2_D42_NAMESPACE;
00257             reg_ns["isis"] = ISIS_NAMESPACE;
00258 
00259             time_t current_time;
00260             time ( &current_time );  //current time
00261             tm * ptm;
00262             ptm = gmtime ( &current_time );
00263 
00264             std::string mon_prefix = (ptm->tm_mon+1 < 10)?"0":"";
00265             std::string day_prefix = (ptm->tm_mday < 10)?"0":"";
00266             std::string hour_prefix = (ptm->tm_hour < 10)?"0":"";
00267             std::string min_prefix = (ptm->tm_min < 10)?"0":"";
00268             std::string sec_prefix = (ptm->tm_sec < 10)?"0":"";
00269             std::stringstream out;
00270             out << ptm->tm_year+1900<<"-"<<mon_prefix<<ptm->tm_mon+1<<"-"<<day_prefix<<ptm->tm_mday<<"T";
00271             out << hour_prefix<<ptm->tm_hour<<":"<<min_prefix<<ptm->tm_min<<":"<<sec_prefix<<ptm->tm_sec;
00272             out << "+0000";
00273 
00274             PayloadSOAP request(reg_ns);
00275             XMLNode op = request.NewChild("isis:RemoveRegistrations");
00276             op.NewChild("ServiceID") = r->serviceid_;
00277             op.NewChild("MessageGenerationTime") = out.str();
00278 
00279             // send
00280             PayloadSOAP *response;
00281             MCCConfig mcc_cfg;
00282             ISIS_description usedISIS = getISIS();
00283             if (!key_.empty())
00284                 mcc_cfg.AddPrivateKey(key_);
00285             if (!cert_.empty())
00286                 mcc_cfg.AddCertificate(cert_);
00287             if (!proxy_.empty())
00288                 mcc_cfg.AddProxy(proxy_);
00289             if (!cadir_.empty())
00290                 mcc_cfg.AddCADir(cadir_);
00291             if (!cafile_.empty())
00292                 mcc_cfg.AddCAFile(cafile_);
00293             logger_.msg(VERBOSE, "Key: %s, Cert: %s, Proxy: %s, CADir: %s CAPath", key_, cert_, proxy_, cadir_, cafile_);
00294 
00295             int retry_ = retry;
00296             while ( retry_ >= 1 ){
00297                 ClientSOAP cli(mcc_cfg,Arc::URL(usedISIS.url),60);
00298                 MCC_Status status = cli.process(&request, &response);
00299 
00300                 std::string response_string;
00301                 (*response).GetDoc(response_string, true);
00302                 logger_.msg(VERBOSE, "Response from the ISIS: %s", response_string);
00303 
00304                 if ((!status.isOk()) ||
00305                     (!response)) {
00306                     logger_.msg(ERROR, "Failed to remove registration from %s ISIS )", usedISIS.url);
00307                 } else {
00308                     if(!(bool)(*response)["RemoveRegistrationResponseElement"])  {
00309                         logger_.msg(VERBOSE, "Successful removed registration from ISIS (%s)", usedISIS.url);
00310                         break;
00311                     } else {
00312                         int i=0;
00313                         while ((bool)(*response)["RemoveRegistrationResponseElement"][i]) {
00314                             logger_.msg(VERBOSE, "Failed to remove registration from ISIS (%s) - %s",
00315                                     usedISIS.url, std::string((*response)["RemoveRegistrationResponseElement"][i]["Fault"]));
00316                             i++;
00317                         }
00318                     }
00319                 }
00320                 retry_--;
00321                 logger_.msg(VERBOSE, "Retry connecting to the ISIS (%s) %d. time(s).", usedISIS.url, retry-retry_);
00322             }
00323 
00324             if (retry_ == 0 )
00325                logger_.msg(VERBOSE, "ISIS (%s) is not available.", usedISIS.url);
00326 
00327             reg_.erase(r);
00328 
00329             logger_.msg(VERBOSE, "Service removed from InfoRegistrar connecting to infosys %s.", myISIS.url);
00330             return true;
00331         };
00332     };
00333     logger_.msg(VERBOSE, "Unregistred Service can not be removed.");
00334     return false;
00335 }
00336 
00337 InfoRegistrar::~InfoRegistrar(void) {
00338     // Registering thread must be stopped before destructor succeeds
00339     Glib::Mutex::Lock lock(lock_);
00340     cond_exit_.signal();
00341     cond_exited_.wait(lock_);
00342 }
00343 
00344 class CondExit {
00345     private:
00346         Glib::Cond& cond_;
00347     public:
00348         CondExit(Glib::Cond& cond):cond_(cond) { };
00349         ~CondExit(void) { cond_.signal(); };
00350 };
00351 
00352 void InfoRegistrar::registration(void) {
00353     Glib::Mutex::Lock lock(lock_);
00354     CondExit cond(cond_exited_);
00355     ISIS_description usedISIS;
00356     std::string isis_name;
00357     if(!myISISList_initialized) getISISList(myISIS);
00358     myISISList_initialized = true;
00359     while(reg_.size() > 0) {
00360         usedISIS = getISIS();
00361         isis_name = usedISIS.url;
00362 
00363         logger_.msg(VERBOSE, "Registration starts: %s",isis_name);
00364         logger_.msg(VERBOSE, "reg_.size(): %d",reg_.size());
00365 
00366         if(usedISIS.url.empty()) {
00367             logger_.msg(WARNING, "Registrant has no proper URL specified. Registration end.");
00368             return;
00369         }
00370         NS reg_ns;
00371         reg_ns["glue2"] = GLUE2_D42_NAMESPACE;
00372         reg_ns["isis"] = ISIS_NAMESPACE;
00373 
00374         // Registration algorithm is stupid and straightforward.
00375         // This part has to be redone to fit P2P network od ISISes
00376 
00377         time_t current_time;
00378         time ( &current_time );  //current time
00379         tm * ptm;
00380         ptm = gmtime ( &current_time );
00381         Time min_reg_time(-1);
00382         XMLNode send_doc(reg_ns, "");
00383 
00384         std::string mon_prefix = (ptm->tm_mon+1 < 10)?"0":"";
00385         std::string day_prefix = (ptm->tm_mday < 10)?"0":"";
00386         std::string hour_prefix = (ptm->tm_hour < 10)?"0":"";
00387         std::string min_prefix = (ptm->tm_min < 10)?"0":"";
00388         std::string sec_prefix = (ptm->tm_sec < 10)?"0":"";
00389         std::stringstream out;
00390         out << ptm->tm_year+1900<<"-"<<mon_prefix<<ptm->tm_mon+1<<"-"<<day_prefix<<ptm->tm_mday<<"T";
00391         out << hour_prefix<<ptm->tm_hour<<":"<<min_prefix<<ptm->tm_min<<":"<<sec_prefix<<ptm->tm_sec;
00392         out << "+0000";
00393 
00394         for(std::list<Register_Info_Type>::iterator r = reg_.begin();
00395                                                r!=reg_.end();++r) {
00396             if ( (r->next_registration).GetTime() <= current_time + stretch_window.GetPeriod() ){
00397                 logger_.msg(VERBOSE,"Create RegEntry XML element");
00398                 Time current(current_time);
00399                 // set the next registration time
00400                 r->next_registration = current + r->period;
00401 
00402                 XMLNode services_doc(reg_ns,"RegEntry");
00403                 if(!((r->p_register)->getService())) continue;
00404                 (r->p_register)->getService()->RegistrationCollector(services_doc);
00405 
00406                 // Fill attributes from InfoRegister configuration
00407                 if (!((bool)services_doc["SrcAdv"]["EPR"]["Address"]) && !((r->endpoint).empty()) ) {
00408                     if (!(bool)services_doc["SrcAdv"]) services_doc.NewChild("SrcAdv");
00409                     if (!(bool)services_doc["SrcAdv"]["EPR"]) services_doc["SrcAdv"].NewChild("EPR");
00410                     if (!(bool)services_doc["SrcAdv"]["EPR"]["Address"]) services_doc["SrcAdv"]["EPR"].NewChild("Address");
00411                     services_doc["SrcAdv"]["EPR"]["Address"] = r->endpoint;
00412                 }
00413 
00414                 if (!((bool)services_doc["MetaSrcAdv"]["ServiceID"]) && !((r->serviceid).empty()) ) {
00415                     if (!(bool)services_doc["MetaSrcAdv"]) services_doc.NewChild("MetaSrcAdv");
00416                     if (!(bool)services_doc["MetaSrcAdv"]["ServiceID"]) services_doc["MetaSrcAdv"].NewChild("ServiceID");
00417                     services_doc["MetaSrcAdv"]["ServiceID"] = r->serviceid;
00418                 }
00419 
00420                 if (!((bool)services_doc["MetaSrcAdv"]["Expiration"]) && !((r->expiration).empty()) ) {
00421                     if (!(bool)services_doc["MetaSrcAdv"]) services_doc.NewChild("MetaSrcAdv");
00422                     if (!(bool)services_doc["MetaSrcAdv"]["Expiration"]) services_doc["MetaSrcAdv"].NewChild("Expiration");
00423                     services_doc["MetaSrcAdv"]["Expiration"] = r->expiration;
00424                 }
00425 
00426                 // Possible completion of the services_doc
00427                 if (!((bool)services_doc["MetaSrcAdv"]["ServiceID"]) && ((bool)services_doc["SrcAdv"]["EPR"]["Address"])) {
00428                     services_doc["MetaSrcAdv"].NewChild("ServiceID") = (std::string) services_doc["SrcAdv"]["EPR"]["Address"];
00429                     logger_.msg(VERBOSE, "ServiceID attribute calculated from Endpoint Reference");
00430                 }
00431                 if (!(bool)services_doc["MetaSrcAdv"]["GenTime"]) {
00432                     services_doc["MetaSrcAdv"].NewChild("GenTime") = out.str();
00433                     logger_.msg(VERBOSE, "Generation Time attribute calculated from current time");
00434                 }
00435 
00436                 // Store the sent ServiceID for the clear shutdown RemoveRegistration operation, if necessary
00437                 if ( (r->serviceid_).empty() &&
00438                      (bool)services_doc["MetaSrcAdv"]["ServiceID"]) {
00439                     r->serviceid_ = (std::string) services_doc["MetaSrcAdv"]["ServiceID"];
00440                     logger_.msg(VERBOSE,"ServiceID stored: %s", r->serviceid_);
00441                 }
00442 
00443                 // TODO check the received registration information
00444                 bool valid_services_doc = true;
00445                 if (!(services_doc.Name() == "RegEntry")) {
00446                     logger_.msg(ERROR,"Missing service document provided by the service %s", r->serviceid_);
00447                     valid_services_doc = false;
00448                 }
00449 
00450                 if (!((bool) services_doc["MetaSrcAdv"]) ||
00451                     !((bool) services_doc["MetaSrcAdv"]["Expiration"])) {
00452                     logger_.msg(ERROR,"Missing MetaServiceAdvertisment or Expiration values provided by the service %s",
00453                                 r->serviceid_);
00454                     valid_services_doc = false;
00455                 }
00456 
00457                 if (!((bool) services_doc["SrcAdv"]) ||
00458                     !((bool) services_doc["SrcAdv"]["Type"])) {
00459                     logger_.msg(ERROR,"Missing Type value provided by the service %s",
00460                                 r->serviceid_);
00461                     valid_services_doc = false;
00462                 }
00463 
00464                 if (!((bool) services_doc["SrcAdv"]) ||
00465                     !((bool) services_doc["SrcAdv"]["EPR"]) ||
00466                     !((bool) services_doc["SrcAdv"]["EPR"]["Address"])) {
00467                     logger_.msg(ERROR,"Missing Endpoint Reference value provided by the service %s",
00468                                 r->serviceid_);
00469                     valid_services_doc = false;
00470                 }
00471 
00472                 if (valid_services_doc) send_doc.NewChild(services_doc);
00473             }
00474             // conditioned minimum search
00475             if ( min_reg_time.GetTime() == -1 ){
00476                 min_reg_time = r->next_registration;
00477             }
00478             else if ( r->next_registration < min_reg_time ) {
00479                 min_reg_time = r->next_registration;
00480             }
00481         }
00482 
00483         // prepare for sending to ISIS
00484         if ( min_reg_time.GetTime() != -1 ) {
00485             logger_.msg(VERBOSE, "Registering to %s ISIS", isis_name);
00486             PayloadSOAP request(reg_ns);
00487             XMLNode op = request.NewChild("isis:Register");
00488             XMLNode header = op.NewChild("isis:Header");
00489             header.NewChild("MessageGenerationTime") = out.str();
00490 
00491             // create body
00492             for(XMLNode node = send_doc["RegEntry"];(bool)node;++node) {
00493                 op.NewChild(node);
00494             }
00495 
00496             // send
00497             PayloadSOAP *response;
00498             MCCConfig mcc_cfg;
00499             if (!key_.empty())
00500                 mcc_cfg.AddPrivateKey(key_);
00501             if (!cert_.empty())
00502                 mcc_cfg.AddCertificate(cert_);
00503             if (!proxy_.empty())
00504                 mcc_cfg.AddProxy(proxy_);
00505             if (!cadir_.empty())
00506                 mcc_cfg.AddCADir(cadir_);
00507             if (!cafile_.empty())
00508                 mcc_cfg.AddCAFile(cafile_);
00509             logger_.msg(VERBOSE, "Key: %s, Cert: %s, Proxy: %s, CADir: %s, CAFile", key_, cert_, proxy_, cadir_, cafile_);
00510 
00511             {std::string services_document;
00512              op.GetDoc(services_document, true);
00513              logger_.msg(VERBOSE, "Sent RegEntries: %s", services_document);
00514             }
00515             //logger_.msg(VERBOSE, "Call the ISIS.process method.");
00516 
00517             int retry_ = retry;
00518             while ( retry_ >= 1 ) {
00519                 ClientSOAP cli(mcc_cfg,Arc::URL(usedISIS.url),60);
00520                 MCC_Status status = cli.process(&request, &response);
00521 
00522                 // multiple tries
00523                 if ((!status.isOk()) ||
00524                     (!response) ||
00525                     (!bool((*response)["RegisterResponse"]))) {
00526                     logger_.msg(ERROR, "Error during registration to %s ISIS", isis_name);
00527                 } else {
00528                     XMLNode fault = (*response)["Fault"];
00529 
00530                     if(!fault)  {
00531                         std::string response_string;
00532                         (*response)["RegisterResponse"].GetDoc(response_string, true);
00533                         logger_.msg(VERBOSE, "Response from the ISIS: %s", response_string);
00534 
00535                         logger_.msg(VERBOSE, "Successful registration to ISIS (%s)", isis_name);
00536                         break;
00537                     } else {
00538                         logger_.msg(VERBOSE, "Failed to register to ISIS (%s) - %s", isis_name, std::string(fault["Description"]));
00539                     }
00540                 }
00541                 retry_--;
00542                 logger_.msg(VERBOSE, "Retry connecting to the ISIS (%s) %d. time(s).", isis_name, retry-retry_);
00543             }
00544             if (response) delete response;
00545 
00546             if ( retry_ == 0 )
00547                 removeISIS(usedISIS);
00548         } // end of the connection with the ISIS
00549 
00550         // Thread sleeping
00551         long int period_ = min_reg_time.GetTime() - current_time;
00552 
00553         logger_.msg(VERBOSE, "Registration ends: %s",isis_name);
00554         logger_.msg(VERBOSE, "Waiting period is %d second(s).",period_);
00555         // The next line is removed for infinite operation
00556         // if(period_ <= 0) break; // One time registration
00557         Glib::TimeVal etime;
00558         etime.assign_current_time();
00559         etime.add_milliseconds(period_*1000L);
00560         // Sleep and exit if interrupted by request to exit
00561         if(cond_exit_.timed_wait(lock_,etime)) break;
00562         //sleep(period_);
00563     }
00564     logger_.msg(VERBOSE, "Registration exit: %s",isis_name);
00565 }
00566 
00567 // -------------------------------------------------------------------
00568 
00569 InfoRegisters::InfoRegisters(XMLNode &cfg, Service *service) {
00570     if(!service) return;
00571     NS ns;
00572     ns["iregc"]=REGISTRATION_CONFIG_NAMESPACE;
00573     cfg.Namespaces(ns);
00574     for(XMLNode node = cfg["iregc:InfoRegistration"];(bool)node;++node) {
00575         registers_.push_back(new InfoRegister(node,service));
00576     }
00577 }
00578 
00579 InfoRegisters::~InfoRegisters(void) {
00580     for(std::list<InfoRegister*>::iterator i = registers_.begin();i!=registers_.end();++i) {
00581         if(*i) delete (*i);
00582     }
00583 }
00584 
00585 // -------------------------------------------------------------------
00586 
00587 } // namespace Arc
00588