Back to index

nordugrid-arc-nox  1.1.0~rc6
SRMClient.cpp
Go to the documentation of this file.
00001 #include <vector>
00002 
00003 #include "SRMClient.h"
00004 #include "SRM1Client.h"
00005 #include "SRM22Client.h"
00006 #include "SRMInfo.h"
00007 
00008 //namespace Arc {
00009   
00010 Arc::Logger SRMClient::logger(Arc::Logger::getRootLogger(), "SRMClient");
00011 
00012   time_t SRMClient::request_timeout=300;
00013   
00014   SRMReturnCode SRMClient::connect(void) {
00015     if(!csoap) return SRM_ERROR_OTHER;
00016     int r = csoap->connect();
00017     if (r == 1) return SRM_ERROR_TEMPORARY;
00018     if (r != 0) return SRM_ERROR_CONNECTION;
00019     return SRM_OK;
00020   }
00021 
00022   SRMClient* SRMClient::getInstance(std::string url,
00023                                     bool& timedout,
00024                                     std::string utils_dir,
00025                                     time_t timeout) {
00026     request_timeout = timeout;
00027     SRMURL srm_url(url);
00028     if (!srm_url) return NULL;
00029   
00030     // can't use ping with srmv1 so just return
00031     if (srm_url.SRMVersion() == SRMURL::SRM_URL_VERSION_1)
00032       return new SRM1Client(srm_url);
00033   
00034     if (utils_dir.empty()) {
00035       if (srm_url.SRMVersion() == SRMURL::SRM_URL_VERSION_2_2) return new SRM22Client(srm_url);
00036       return NULL;
00037     }
00038       
00039     SRMReturnCode srm_error;
00040     std::string version;
00041   
00042     SRMInfo info(utils_dir);
00043     SRMFileInfo srm_file_info;
00044     // lists of ports and protocols in the order to try them
00045     std::vector<int> ports;
00046     ports.push_back(srm_url.Port());
00047     if (srm_url.Port() != 8443) ports.push_back(8443);
00048     if (srm_url.Port() != 8446) ports.push_back(8446);
00049     if (srm_url.Port() != 8444) ports.push_back(8444);
00050     std::vector<std::string> protocols;
00051     if (srm_url.GSSAPI()) {
00052       protocols.push_back("gssapi");
00053       protocols.push_back("gsi");
00054     }
00055     else {
00056       protocols.push_back("gsi");
00057       protocols.push_back("gssapi");
00058     }    
00059     
00060     srm_file_info.host = srm_url.Host();
00061     srm_file_info.version = srm_url.SRMVersion();
00062     
00063     // no info
00064     if (!info.getSRMFileInfo(srm_file_info)) {
00065       for (std::vector<std::string>::iterator protocol = protocols.begin(); protocol != protocols.end(); protocol++) {
00066         srm_url.GSSAPI((*protocol == "gssapi") ? true : false);
00067         for (std::vector<int>::iterator port = ports.begin(); port != ports.end(); port++) {
00068           logger.msg(Arc::VERBOSE, "Attempting to contact %s on port %i using protocol %s", srm_url.Host(), *port, *protocol);
00069           srm_url.SetPort(*port);
00070           SRMClient * client = new SRM22Client(srm_url);
00071       
00072           if ((srm_error = client->ping(version, false)) == SRM_OK) {
00073             srm_file_info.port = *port;
00074             srm_file_info.protocol = *protocol;
00075             logger.msg(Arc::VERBOSE, "Storing port %i and protocol %s for %s", *port, *protocol, srm_url.Host());
00076             info.putSRMFileInfo(srm_file_info);
00077             return client;
00078           }
00079           delete client;
00080           if (srm_error == SRM_ERROR_TEMPORARY) {
00081             // probably correct port and protocol and service is down
00082             // but don't want to risk storing incorrect info
00083             timedout = true;
00084             return NULL;
00085           }
00086         }
00087       }
00088       // if we get here no combination has worked
00089       logger.msg(Arc::VERBOSE, "No combination of port and protocol succeeded for %s", srm_url.Host());
00090       return NULL;
00091     }
00092     // url agrees with file info
00093     else if (srm_file_info == srm_url) {
00094       srm_url.SetPort(srm_file_info.port);
00095       srm_url.GSSAPI((srm_file_info.protocol == "gssapi") ? true : false);
00096       return new SRM22Client(srm_url);
00097     }
00098     // url disagrees with file info
00099     else {
00100       // ping and if ok, replace file info
00101       logger.msg(Arc::VERBOSE, "URL %s disagrees with stored SRM info, testing new info", srm_url.ShortURL());
00102       SRMClient * client = new SRM22Client(srm_url);
00103   
00104       if ((srm_error = client->ping(version, false)) == SRM_OK) {
00105         srm_file_info.port = srm_url.Port();
00106         srm_file_info.protocol = srm_url.GSSAPI()? "gssapi" : "gsi";
00107         logger.msg(Arc::VERBOSE, "Replacing old SRM info with new for URL %s", srm_url.ShortURL());
00108         info.putSRMFileInfo(srm_file_info);
00109         return client;
00110       }
00111       delete client;
00112       if (srm_error == SRM_ERROR_TEMPORARY) {
00113         // probably correct port and protocol and service is down
00114         // but don't want to risk storing incorrect info
00115         timedout = true;
00116       }
00117       return NULL;
00118     }
00119  }
00120 //} // namespace Arc