Back to index

nordugrid-arc-nox  1.1.0~rc6
isistest.cpp
Go to the documentation of this file.
00001 
00002 #include <sys/stat.h>
00003 #include <time.h>
00004 #include <fstream>
00005 #include <sstream>
00006 #include <algorithm>
00007 #include <vector>
00008 
00009 #include <arc/IString.h>
00010 #include <arc/Logger.h>
00011 #include <arc/OptionParser.h>
00012 #include <arc/StringConv.h>
00013 #include <arc/UserConfig.h>
00014 #include <arc/URL.h>
00015 #include <arc/XMLNode.h>
00016 #include <arc/client/ClientInterface.h>
00017 #include <arc/message/MCCLoader.h>
00018 #include <arc/message/PayloadSOAP.h>
00019 
00020 Arc::Logger logger(Arc::Logger::rootLogger, "ISISTest");
00021 
00022 // Query function
00023 std::string Query( Arc::URL url, std::string query, Arc::UserConfig usercfg ){
00024     Arc::MCCConfig mcc_cfg;
00025     usercfg.ApplyToConfig(mcc_cfg);
00026     Arc::ClientSOAP client_entry(mcc_cfg, url, usercfg.Timeout());
00027 
00028     // Create and send Query request
00029     logger.msg(Arc::INFO, "Creating and sending request");
00030     Arc::NS query_ns;
00031     query_ns[""] = "http://www.nordugrid.org/schemas/isis/2007/06";
00032     Arc::PayloadSOAP req(query_ns);
00033     Arc::XMLNode request = req.NewChild("Query");
00034     request.NewChild("QueryString") = query;
00035 
00036     std::string request_string;
00037     request.GetDoc(request_string,true);
00038     logger.msg(Arc::DEBUG, "Request: %s", request_string);
00039 
00040     Arc::MCC_Status status;
00041     Arc::PayloadSOAP *resp = NULL;
00042     std::cout << " Request sent. Waiting for the response." << std::endl;
00043     status= client_entry.process(&req,&resp);
00044 
00045     if ( (!status.isOk()) || (!resp) || (resp->IsFault()) ) {
00046       logger.msg(Arc::ERROR, "Request failed");
00047       std::cerr << "Status: " << std::string(status) << std::endl;
00048       return "-1";
00049     };
00050 
00051     std::string response_string;
00052     (*resp).GetDoc(response_string,true);
00053     logger.msg(Arc::DEBUG, "Response: %s", response_string);
00054 
00055     //The response message
00056     std::string response = "";
00057     if (bool((*resp)["QueryResponse"]) ){
00058           std::string xml;
00059           (*resp)["QueryResponse"].GetDoc(xml, true);
00060           response += xml;
00061           response +="\n";
00062     }
00063 
00064     return response;
00065 }
00066 
00067 
00068 // Register function
00069 std::string Register( Arc::URL url, std::vector<std::string> &serviceID, std::vector<std::string> &epr,
00070                       std::vector<std::string> type, std::vector<std::string> expiration, Arc::UserConfig usercfg ){
00071 
00072     if (serviceID.size() != epr.size()){
00073        logger.msg(Arc::VERBOSE, " Service_ID's number is not equivalent with the EPR's number!");
00074        return "-1";
00075     }
00076 
00077     Arc::MCCConfig mcc_cfg;
00078     usercfg.ApplyToConfig(mcc_cfg);
00079     Arc::ClientSOAP client_entry(mcc_cfg, url, usercfg.Timeout());
00080 
00081     // Create and send Register request
00082     logger.msg(Arc::INFO, "Creating and sending request");
00083     Arc::NS query_ns;
00084     //query_ns[""] = "http://www.nordugrid.org/schemas/isis/2007/06";
00085     query_ns["wsa"] = "http://www.w3.org/2005/08/addressing";
00086     Arc::PayloadSOAP req(query_ns);
00087 
00088     Arc::XMLNode request = req.NewChild("Register");
00089     request.NewChild("Header");
00090     //request["Header"].NewChild("RequesterID");
00091 
00092     time_t rawtime;
00093     time ( &rawtime );  //current time
00094     tm * ptm;
00095     ptm = gmtime ( &rawtime );
00096 
00097     std::string mon_prefix = (ptm->tm_mon+1 < 10)?"0":"";
00098     std::string day_prefix = (ptm->tm_mday < 10)?"0":"";
00099     std::string hour_prefix = (ptm->tm_hour < 10)?"0":"";
00100     std::string min_prefix = (ptm->tm_min < 10)?"0":"";
00101     std::string sec_prefix = (ptm->tm_sec < 10)?"0":"";
00102     std::stringstream out;
00103     out << ptm->tm_year+1900<<"-"<<mon_prefix<<ptm->tm_mon+1<<"-"<<day_prefix<<ptm->tm_mday<<"T"<<hour_prefix<<ptm->tm_hour<<":"<<min_prefix<<ptm->tm_min<<":"<<sec_prefix<<ptm->tm_sec<<"+0000";
00104     request["Header"].NewChild("MessageGenerationTime") = out.str();
00105 
00106     for (int i=0; i < serviceID.size(); i++){
00107         Arc::XMLNode srcAdv = request.NewChild("RegEntry").NewChild("SrcAdv");
00108         srcAdv.NewChild("Type") = type[i];
00109         Arc::XMLNode epr_xmlnode = srcAdv.NewChild("EPR");
00110         epr_xmlnode.NewChild("Address") = epr[i];
00111         //srcAdv.NewChild("SSPair");
00112 
00113         Arc::XMLNode metaSrcAdv = request["RegEntry"][i].NewChild("MetaSrcAdv");
00114         metaSrcAdv.NewChild("ServiceID") = serviceID[i];
00115         metaSrcAdv.NewChild("GenTime") = out.str();
00116         metaSrcAdv.NewChild("Expiration") = expiration[i];
00117     }
00118 
00119     std::string request_string;
00120     request.GetDoc(request_string,true);
00121     logger.msg(Arc::DEBUG, "Request: %s", request_string);
00122 
00123     Arc::MCC_Status status;
00124     Arc::PayloadSOAP *resp = NULL;
00125     std::cout << " Request sent. Waiting for the response." << std::endl;
00126     status= client_entry.process(&req,&resp);
00127 
00128     if ( (!status.isOk()) || (!resp) || (resp->IsFault()) ) {
00129       logger.msg(Arc::ERROR, "Request failed");
00130       std::cerr << "Status: " << std::string(status) << std::endl;
00131       return "-1";
00132     };
00133 
00134     std::string response_string;
00135     (*resp).GetDoc(response_string,true);
00136     logger.msg(Arc::DEBUG, "Response: %s", response_string);
00137 
00138     //The response message
00139     std::string response = "";
00140     if (bool((*resp)["RegisterResponse"]) ){
00141           std::string xml;
00142           (*resp)["RegisterResponse"].GetDoc(xml, true);
00143           response += xml;
00144           response +="\n";
00145     }
00146 
00147     return response;
00148 }
00149 
00150 
00151 // RemoveRegistration function
00152 std::string RemoveRegistration( Arc::URL url, std::vector<std::string> &serviceID, Arc::UserConfig usercfg ){
00153     Arc::MCCConfig mcc_cfg;
00154     usercfg.ApplyToConfig(mcc_cfg);
00155     Arc::ClientSOAP client_entry(mcc_cfg, url, usercfg.Timeout());
00156 
00157     // Create and send RemoveRegistrations request
00158     logger.msg(Arc::INFO, "Creating and sending request");
00159     Arc::NS query_ns;
00160     query_ns[""] = "http://www.nordugrid.org/schemas/isis/2007/06";
00161     Arc::PayloadSOAP req(query_ns);
00162 
00163     Arc::XMLNode request = req.NewChild("RemoveRegistrations");
00164     for (std::vector<std::string>::const_iterator it = serviceID.begin(); it != serviceID.end(); it++){
00165         request.NewChild("ServiceID") = *it;
00166     }
00167     time_t rawtime;
00168     time ( &rawtime );  //current time
00169     tm * ptm;
00170     ptm = gmtime ( &rawtime );
00171 
00172     std::string mon_prefix = (ptm->tm_mon+1 < 10)?"0":"";
00173     std::string day_prefix = (ptm->tm_mday < 10)?"0":"";
00174     std::string hour_prefix = (ptm->tm_hour < 10)?"0":"";
00175     std::string min_prefix = (ptm->tm_min < 10)?"0":"";
00176     std::string sec_prefix = (ptm->tm_sec < 10)?"0":"";
00177     std::stringstream out;
00178     out << ptm->tm_year+1900<<"-"<<mon_prefix<<ptm->tm_mon+1<<"-"<<day_prefix<<ptm->tm_mday<<"T"<<hour_prefix<<ptm->tm_hour<<":"<<min_prefix<<ptm->tm_min<<":"<<sec_prefix<<ptm->tm_sec<<"+0000";
00179     request.NewChild("MessageGenerationTime") = out.str();
00180 
00181     std::string request_string;
00182     request.GetDoc(request_string,true);
00183     logger.msg(Arc::DEBUG, "Request: %s", request_string);
00184 
00185     Arc::MCC_Status status;
00186     Arc::PayloadSOAP *resp = NULL;
00187     std::cout << " Request sent. Waiting for the response." << std::endl;
00188     status= client_entry.process(&req,&resp);
00189 
00190     if ( (!status.isOk()) || (!resp) || (resp->IsFault()) ) {
00191       logger.msg(Arc::ERROR, "Request failed");
00192       std::cerr << "Status: " << std::string(status) << std::endl;
00193       return "-1";
00194     };
00195 
00196     std::string response_string;
00197     (*resp).GetDoc(response_string,true);
00198     logger.msg(Arc::DEBUG, "Response: %s", response_string);
00199 
00200     //The response message
00201     std::string response = "";
00202     if (bool((*resp)["RemoveRegistrationsResponse"]) ){
00203           std::string xml;
00204           (*resp)["RemoveRegistrationsResponse"].GetDoc(xml, true);
00205           response += xml;
00206           response +="\n";
00207     }
00208 
00209     return response;
00210 }
00211 
00212 // GetISISList function
00213 std::vector<std::string> GetISISList( Arc::URL url, Arc::UserConfig usercfg ){
00214 
00215     //The response vector
00216     std::vector<std::string> response;
00217 
00218     Arc::MCCConfig mcc_cfg;
00219     usercfg.ApplyToConfig(mcc_cfg);
00220     Arc::ClientSOAP client_entry(mcc_cfg, url, usercfg.Timeout());
00221 
00222     // Create and send GetISISList request
00223     logger.msg(Arc::INFO, "Creating and sending request");
00224     Arc::NS query_ns;
00225     query_ns[""] = "http://www.nordugrid.org/schemas/isis/2007/06";
00226     Arc::PayloadSOAP req(query_ns);
00227     Arc::XMLNode request = req.NewChild("GetISISList");
00228 
00229     std::string request_string;
00230     request.GetDoc(request_string,true);
00231     logger.msg(Arc::DEBUG, "Request: %s", request_string);
00232 
00233     Arc::MCC_Status status;
00234     Arc::PayloadSOAP *resp = NULL;
00235     std::cout << " Request sent. Waiting for the response." << std::endl;
00236     status= client_entry.process(&req,&resp);
00237 
00238     if ( (!status.isOk()) || (!resp) || (resp->IsFault()) ) {
00239       logger.msg(Arc::ERROR, "Request failed");
00240       std::cerr << "Status: " << std::string(status) << std::endl;
00241       return response;
00242     };
00243 
00244     std::string response_string;
00245     (*resp).GetDoc(response_string,true);
00246     logger.msg(Arc::DEBUG, "Response: %s", response_string);
00247 
00248     // Construct the response vector
00249     if (bool((*resp)["GetISISListResponse"]) ){
00250         int i = 0;
00251         while((bool)(*resp)["GetISISListResponse"]["EPR"][i]) {
00252             response.push_back((std::string)(*resp)["GetISISListResponse"]["EPR"][i]);
00253             i++;
00254         }
00255     }
00256 
00257     return response;
00258 }
00259 
00260 // Split the given string by the given delimiter and return its parts
00261 std::vector<std::string> split( const std::string original_string, const std::string delimiter ) {
00262     std::vector<std::string> retVal;
00263     unsigned long start=0;
00264     unsigned long end;
00265     while ( ( end = original_string.find( delimiter, start ) ) != std::string::npos ) {
00266           retVal.push_back( original_string.substr( start, end-start ) );
00267           start = end + 1;
00268     }
00269     retVal.push_back( original_string.substr( start ) );
00270     return retVal;
00271 }
00272 
00273 
00274 int main(int argc, char** argv) {
00275 
00276     Arc::LogStream logcerr(std::cerr);
00277     logcerr.setFormat(Arc::ShortFormat);
00278     Arc::Logger::getRootLogger().addDestination(logcerr);
00279     Arc::Logger::getRootLogger().setThreshold(Arc::WARNING);
00280 
00281     Arc::OptionParser options(istring("[ISIS testing ...]"),
00282       istring("This tiny tool can be used for testing "
00283               "the ISIS's abilities."),
00284       istring("The method are the folows: Query, Register, RemoveRegistration")
00285       );
00286 
00287     std::string infosys_url = "";
00288       options.AddOption('b', "bootstrap",
00289         istring("define the URL of the Bootstrap ISIS"),
00290         istring("isis"),
00291         infosys_url);
00292 
00293     std::string isis_url = "";
00294       options.AddOption('i', "isis",
00295         istring("define the URL of the ISIS to connect directly"),
00296         istring("isis"),
00297         isis_url);
00298 
00299     std::string method = "";
00300       options.AddOption('m', "method",
00301         istring("define which method are use (Query, Register, RemoveRegistration)"),
00302         istring("method"),
00303         method);
00304 
00305     std::string debug;
00306       options.AddOption('d', "debug",
00307                 istring("FATAL, ERROR, WARNING, INFO, VERBOSE or DEBUG"),
00308                 istring("debuglevel"), debug);
00309 
00310     bool neighbors = false;
00311       options.AddOption('n', "neighbors",
00312                 istring("get neighbors list from the BootstrapISIS"),
00313                 neighbors);
00314 
00315     std::string conffile;
00316       options.AddOption('z', "conffile",
00317                 istring("configuration file (default ~/.arc/client.conf)"),
00318                 istring("filename"), conffile);
00319 
00320     std::list<std::string> parameters = options.Parse(argc, argv);
00321     if (!method.empty() && parameters.empty()) {
00322        std::cout << "Use --help option for detailed usage information" << std::endl;
00323        return 1;
00324     }
00325 
00326     if (!debug.empty())
00327        Arc::Logger::getRootLogger().setThreshold(Arc::string_to_level(debug));
00328 
00329     // Create UserConfig
00330     Arc::UserConfig usercfg(conffile);
00331 
00332     std::cout << " [ ISIS tester ] " << std::endl;
00333     // Read the first ISIS from the client configuration
00334     if (isis_url.empty()) {
00335         Arc::URLListMap ulm = usercfg.GetSelectedServices(Arc::INDEX);
00336         if (ulm.find("ARC1") != ulm.end()) {
00337             std::list<Arc::URL> isisFromConfig = ulm.find("ARC1")->second;
00338             if (!isisFromConfig.empty()){
00339                 isis_url = (*isisFromConfig.begin()).fullstr();
00340                 std::cout << " The following URL from client confifuration will be used: " << isis_url << std::endl;
00341             }
00342         }
00343     }
00344 
00345     if (isis_url.empty() && infosys_url.empty()) {
00346         std::cout << "ISIS or Bootstrap ISIS have to be defined. Please use -i or -b options. For further options see --help" << std::endl;
00347         return 1;
00348     }
00349 
00350     logger.msg(Arc::INFO, " ISIS tester start!");
00351 
00352     std::string contactISIS_address_ = "";
00353 
00354     if (isis_url.empty() || neighbors) {
00355         if ( !isis_url.empty() && neighbors ) infosys_url = isis_url;
00356         Arc::URL BootstrapISIS(infosys_url);
00357 
00358         // Get the a list of known ISIS's and choose one from them randomly
00359         std::vector<std::string> neighbors_ = GetISISList( BootstrapISIS, usercfg );
00360 
00361         std::srand(time(NULL));
00362         if (neighbors) {
00363             for (std::vector<std::string>::const_iterator it = neighbors_.begin(); it < neighbors_.end(); it++) {
00364                 std::cout << " Neighbor: " << (*it) << std::endl;
00365             }
00366         }
00367         if (isis_url.empty()) {
00368             contactISIS_address_ = neighbors_[std::rand() % neighbors_.size()];
00369             std::cout << " The choosen ISIS list for contact detailed information: " << contactISIS_address_ << std::endl;
00370         }
00371         else contactISIS_address_ = isis_url;
00372     } else {
00373         contactISIS_address_ = isis_url;
00374     }
00375     Arc::URL ContactISIS(contactISIS_address_);
00376     // end of getISISList
00377 
00378     if (!method.empty()) { std::cout << " [ The selected method:  " << method << " ] " << std::endl; }
00379     std::string response = "";
00380     //The method is Query
00381     if (method == "Query"){
00382        std::string query_string = "";
00383        for (std::list<std::string>::const_iterator it=parameters.begin(); it!=parameters.end(); it++){
00384            query_string += " " + *it;
00385        }
00386        response = Query( ContactISIS, *parameters.begin(), usercfg );
00387        if ( response != "-1" ){
00388           Arc::XMLNode resp(response);
00389           Arc::XMLNode queryresponse_;
00390           resp["Body"]["QueryResponse"].New(queryresponse_);
00391           queryresponse_.GetDoc(response, true);
00392           std::cout << " The Query response: " << response << std::endl;
00393        }
00394     }
00395     //The method is Register
00396     else if (method == "Register"){
00397        std::vector<std::string> serviceID;
00398        std::vector<std::string> epr;
00399        std::vector<std::string> type;
00400        std::vector<std::string> expiration;
00401 
00402        for (std::list<std::string>::const_iterator it=parameters.begin(); it!=parameters.end(); it++){
00403            std::vector<std::string> Elements = split( *it, "," );
00404            if ( Elements.size() >= 2 && Elements.size() <= 4 ) {
00405               serviceID.push_back(Elements[0]);
00406               epr.push_back(Elements[1]);
00407               if ( Elements.size() >= 3 ) type.push_back(Elements[2]);
00408               else type.push_back("org.nordugrid.tests.isistest");
00409               if ( Elements.size() >= 4 ) expiration.push_back(Elements[3]);
00410               else expiration.push_back("PT30M");
00411            }
00412            else {
00413               logger.msg(Arc::ERROR, " Not enough or too much parameters! %s", *it);
00414               return 1;
00415            }
00416        }
00417        response = Register( ContactISIS, serviceID, epr, type, expiration, usercfg );
00418        if ( response != "-1" ){
00419           Arc::XMLNode resp(response);
00420           if ( bool(resp["Body"]["Fault"]) ){
00421              std::cout << " The Registeration failed!" << std::endl;
00422              std::cout << " The fault's name: " << (std::string)resp["Body"]["Fault"]["Name"] << std::endl;
00423              std::cout << " The fault's type: " << (std::string)resp["Body"]["Fault"]["Type"] << std::endl;
00424              std::cout << " The fault's description: " << (std::string)resp["Body"]["Fault"]["Description"] << std::endl;
00425           }
00426           else {
00427              std::cout << " The Register method succeeded." << std::endl;
00428           }
00429        }
00430     }
00431     //The method is RemoveRegistration
00432     else if (method == "RemoveRegistration"){
00433        std::vector<std::string> serviceID;
00434 
00435        for (std::list<std::string>::const_iterator it=parameters.begin(); it!=parameters.end(); it++){
00436               serviceID.push_back(*it);
00437        }
00438        response = RemoveRegistration( ContactISIS, serviceID, usercfg );
00439        if ( response != "-1" ){
00440           Arc::XMLNode resp(response);
00441           int i=0;
00442           Arc::XMLNode responsElements = resp["Body"]["RemoveRegistrationsResponse"]["RemoveRegistrationResponseElement"];
00443           while ( bool(responsElements[i]) ){
00444              std::cout << " The RemoveRegistration failed!" << std::endl;
00445              std::cout << " The ServiceID: " << (std::string)responsElements[i]["ServiceID"] << std::endl;
00446              std::cout << " The fault's name: " << (std::string)responsElements[i]["Fault"]["Name"] << std::endl;
00447              std::cout << " The fault's type: " << (std::string)responsElements[i]["Fault"]["Type"] << std::endl;
00448              std::cout << " The fault's description: " << (std::string)responsElements[i]["Fault"]["Description"] << std::endl;
00449              i++;
00450           }
00451 
00452           if (i == 0) {
00453              std::cout << " The RemoveRegistration method succeeded." << std::endl;
00454           }
00455        }
00456     }
00457     else {
00458        std::cout << " [ Method is missing! ] " << std::endl;
00459        return 0;
00460     }
00461 
00462     // When any problem is by the SOAP message.
00463     if ( response == "-1" ){
00464        std::cout << " No response message or other error in the " << method << " process!" << std::endl;
00465        return 1;
00466     }
00467 
00468     return 0;
00469 }
00470