Back to index

nordugrid-arc-nox  1.1.0~rc6
SRM1Client.cpp
Go to the documentation of this file.
00001 #include "SRM1Client.h"
00002 
00003 //namespace Arc {
00004 
00005   //Logger SRM1Client::logger(SRMClient::logger, "SRM1Client");
00006   
00007   SRM1Client::SRM1Client(SRMURL url) {
00008     version = "v1";
00009     implementation = SRM_IMPLEMENTATION_UNKNOWN;
00010     service_endpoint = url.ContactURL();
00011     csoap = new Arc::HTTPSClientSOAP(service_endpoint.c_str(),&soapobj,url.GSSAPI(),request_timeout,false);
00012     if(!csoap) { csoap=NULL; return; };
00013     if(!*csoap) { delete csoap; csoap=NULL; return; };
00014     soapobj.namespaces=srm1_soap_namespaces;
00015   }
00016   
00017   SRM1Client::~SRM1Client(void) {
00018     if(csoap) { csoap->disconnect(); delete csoap; };
00019   }
00020   
00021   static const char* Supported_Protocols[] = {
00022     "gsiftp","https","httpg","http","ftp","se"
00023   };
00024   
00025   SRMReturnCode SRM1Client::getTURLs(SRMClientRequest& req,
00026                                      std::list<std::string>& urls) {
00027     SRMReturnCode rc = connect();
00028     if (rc != SRM_OK) return rc;
00029 
00030     SRMURL srmurl(req.surls().front().c_str());
00031     int soap_err = SOAP_OK;
00032     std::list<int> file_ids;
00033     ArrayOfstring* SURLs = soap_new_ArrayOfstring(&soapobj,-1);
00034     ArrayOfstring* Protocols = soap_new_ArrayOfstring(&soapobj,-1);
00035     struct SRMv1Meth__getResponse r; r._Result=NULL;
00036     if((!SURLs) || (!Protocols)) {
00037       csoap->reset(); return SRM_ERROR_OTHER;
00038     };
00039     Protocols->__ptr=(char**)Supported_Protocols;
00040     Protocols->__size=sizeof(Supported_Protocols)/sizeof(Supported_Protocols[0]);
00041     std::string file_url = srmurl.FullURL();
00042     const char* surl[] = { file_url.c_str() };
00043     SURLs->__ptr=(char**)surl;
00044     SURLs->__size=1;
00045     if((soap_err=soap_call_SRMv1Meth__get(&soapobj,csoap->SOAP_URL(),"get",SURLs,Protocols,r)) != SOAP_OK) {
00046       logger.msg(Arc::INFO, "SOAP request failed (get)");
00047       if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00048       csoap->disconnect();
00049       return SRM_ERROR_SOAP;
00050     };
00051     if(r._Result == NULL) {  
00052       logger.msg(Arc::INFO, "SRM did not return any information");
00053       return SRM_ERROR_OTHER;
00054     };
00055     char* request_state = r._Result->state;
00056     req.request_id(r._Result->requestId);
00057     SRMv1Type__RequestStatus& result = *(r._Result);
00058     time_t t_start = time(NULL);
00059     for(;;) {
00060       ArrayOfRequestFileStatus* fstatus = result.fileStatuses;
00061       if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
00062         for(int n=0;n<fstatus->__size;n++) {
00063           SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
00064           if(fs && fs->state && (strcasecmp(fs->state,"ready") == 0)) {
00065             if(fs->TURL) {
00066               urls.push_back(std::string(fs->TURL));
00067               file_ids.push_back(fs->fileId);
00068             };
00069           };
00070         };
00071       };
00072       if(urls.size()) break; // Have requested data
00073       if(!request_state) break; // No data and no state - fishy
00074       if(strcasecmp(request_state,"pending") != 0) break;
00075       if((time(NULL) - t_start) > request_timeout) break;
00076       if(result.retryDeltaTime < 1) result.retryDeltaTime=1;
00077       if(result.retryDeltaTime > 10) result.retryDeltaTime=10;
00078       sleep(result.retryDeltaTime);
00079       SRMv1Meth__getRequestStatusResponse r;
00080       if((soap_err=soap_call_SRMv1Meth__getRequestStatus(&soapobj,csoap->SOAP_URL(),
00081                "getRequestStatus",req.request_id(),r)) != SOAP_OK) {
00082         logger.msg(Arc::INFO, "SOAP request failed (getRequestStatus)");
00083         if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00084         csoap->disconnect();
00085         return SRM_ERROR_SOAP;
00086       };
00087       if(r._Result == NULL) {  
00088         logger.msg(Arc::INFO, "SRM did not return any information");
00089         return SRM_ERROR_OTHER;
00090       };
00091       request_state = r._Result->state;
00092       result = *(r._Result);
00093     };
00094     req.file_ids(file_ids);
00095     if(urls.size() == 0) return SRM_ERROR_OTHER;
00096     return acquire(req,urls);
00097   }
00098   
00099   SRMReturnCode SRM1Client::putTURLs(SRMClientRequest& req,
00100                                      std::list<std::string>& urls,
00101                                      unsigned long long size) {
00102     SRMReturnCode rc = connect();
00103     if (rc != SRM_OK) return rc;
00104   
00105     SRMURL srmurl(req.surls().front().c_str());
00106     int soap_err = SOAP_OK;
00107     std::list<int> file_ids;
00108     // Request place for new file to put
00109     ArrayOfstring* src_file_names = soap_new_ArrayOfstring(&soapobj,-1);
00110     ArrayOfstring* dst_file_names = soap_new_ArrayOfstring(&soapobj,-1);
00111     ArrayOflong* sizes = soap_new_ArrayOflong(&soapobj,-1);
00112     ArrayOfboolean* wantPermanent = soap_new_ArrayOfboolean(&soapobj,-1);
00113     ArrayOfstring* protocols = soap_new_ArrayOfstring(&soapobj,-1);
00114     struct SRMv1Meth__putResponse r; r._Result=NULL;
00115     //r._Result=soap_new_SRMv1Type__RequestStatus(&soapobj,-1);
00116     if((!src_file_names) || (!dst_file_names) || (!sizes) || 
00117        (!wantPermanent) || (!protocols)) {
00118       csoap->reset(); return SRM_ERROR_OTHER;
00119     };
00120     protocols->__ptr=(char**)Supported_Protocols;
00121     protocols->__size=sizeof(Supported_Protocols)/sizeof(Supported_Protocols[0]);
00122     LONG64 sizes_[] = { size }; // TODO
00123     bool wantPermanent_[] = { true };
00124     std::string file_url = srmurl.FullURL();
00125     const char* surl[] = { file_url.c_str() };
00126     src_file_names->__ptr=(char**)surl; src_file_names->__size=1;
00127     dst_file_names->__ptr=(char**)surl; dst_file_names->__size=1;
00128     sizes->__ptr=sizes_; sizes->__size=1;
00129     wantPermanent->__ptr=wantPermanent_; wantPermanent->__size=1;
00130     if((soap_err=soap_call_SRMv1Meth__put(&soapobj,csoap->SOAP_URL(),"put",
00131                  src_file_names,dst_file_names,sizes,
00132                  wantPermanent,protocols,r)) != SOAP_OK) {
00133       logger.msg(Arc::INFO, "SOAP request failed (put)");
00134       if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00135       csoap->disconnect();
00136       return SRM_ERROR_SOAP;
00137     };
00138     if(r._Result == NULL) {
00139       logger.msg(Arc::INFO, "SRM did not return any information");
00140       return SRM_ERROR_OTHER;
00141     };
00142     char* request_state = r._Result->state;
00143     req.request_id(r._Result->requestId);
00144     SRMv1Type__RequestStatus* result = r._Result;
00145     time_t t_start = time(NULL);
00146     // Ask for request state in loop till SRM server returns  
00147     // request status !Pending and file status ready
00148     for(;;) {
00149       ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
00150       if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
00151         for(int n=0;n<fstatus->__size;n++) {
00152           SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
00153           if(fs && fs->state && (strcasecmp(fs->state,"ready") == 0)) {
00154             if(fs->TURL) {
00155               urls.push_back(std::string(fs->TURL));
00156               file_ids.push_back(fs->fileId);
00157             };
00158           };
00159         };
00160       };
00161       if(urls.size()) break; // Have requested data
00162       if(!request_state) break; // No data and no state - fishy
00163       // Leave if state is not pending and no endpoints 
00164       if(strcasecmp(request_state,"pending") != 0) break;
00165       if((time(NULL) - t_start) > request_timeout) break;
00166       if(result->retryDeltaTime < 1) result->retryDeltaTime=1;
00167       if(result->retryDeltaTime > 10) result->retryDeltaTime=10;
00168       sleep(result->retryDeltaTime);
00169       SRMv1Meth__getRequestStatusResponse r;
00170       if((soap_err=soap_call_SRMv1Meth__getRequestStatus(&soapobj,csoap->SOAP_URL(),
00171                "getRequestStatus",req.request_id(),r)) != SOAP_OK) {
00172         logger.msg(Arc::INFO, "SOAP request failed (getRequestStatus)");
00173         if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00174         csoap->disconnect();
00175         return SRM_ERROR_SOAP;
00176       };
00177       if(r._Result == NULL) {
00178         logger.msg(Arc::INFO, "SRM did not return any information");
00179         return SRM_ERROR_OTHER;
00180       };
00181       request_state = r._Result->state;
00182       result = r._Result;
00183     };
00184     req.file_ids(file_ids);
00185     if(urls.size() == 0) return SRM_ERROR_OTHER;
00186     return acquire(req,urls);
00187   }
00188   
00189   SRMReturnCode SRM1Client::copy(SRMClientRequest& req,
00190                                  const std::string& source) {
00191     SRMReturnCode rc = connect();
00192     if (rc != SRM_OK) return rc;
00193   
00194     SRMURL srmurl(req.surls().front().c_str());
00195     int soap_err = SOAP_OK;
00196     std::list<int> file_ids;
00197     // Request place for new file to put
00198     ArrayOfstring* src_file_names = soap_new_ArrayOfstring(&soapobj,-1);
00199     ArrayOfstring* dst_file_names = soap_new_ArrayOfstring(&soapobj,-1);
00200     ArrayOfboolean* bools = soap_new_ArrayOfboolean(&soapobj,-1);
00201     struct SRMv1Meth__copyResponse r; r._Result=NULL;
00202     if((!src_file_names) || (!dst_file_names)) {
00203       csoap->reset(); return SRM_ERROR_OTHER;
00204     };
00205     std::string file_url = srmurl.FullURL();
00206     const char* surl[] = { file_url.c_str() };
00207     const char* srcurl[] = { source.c_str() };
00208     bool bools_[] = { false };
00209     src_file_names->__ptr=(char**)srcurl; src_file_names->__size=1;
00210     dst_file_names->__ptr=(char**)surl; dst_file_names->__size=1;
00211     bools->__ptr=bools_; bools->__size=1;
00212     if((soap_err=soap_call_SRMv1Meth__copy(&soapobj,csoap->SOAP_URL(),"copy",
00213                  src_file_names,dst_file_names,bools,r)) != SOAP_OK) {
00214       logger.msg(Arc::INFO, "SOAP request failed (copy)");
00215       if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00216       csoap->disconnect();
00217       return SRM_ERROR_SOAP;
00218     };
00219     if(r._Result == NULL) {
00220       logger.msg(Arc::INFO, "SRM did not return any information");
00221       return SRM_ERROR_OTHER;
00222     };
00223     char* request_state = r._Result->state;
00224     req.request_id(r._Result->requestId);
00225     SRMv1Type__RequestStatus* result = r._Result;
00226     time_t t_start = time(NULL);
00227     // Ask for request state in loop till SRM server returns
00228     // request status !Pending and file status Ready
00229     for(;;) {
00230       ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
00231       if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
00232         for(int n=0;n<fstatus->__size;n++) {
00233           SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
00234           if(fs && fs->state && (strcasecmp(fs->state,"ready") == 0)) {
00235             file_ids.push_back(fs->fileId);
00236           };
00237         };
00238       };
00239       if(file_ids.size()) break; // Have requested data
00240       if(!request_state) break; // No data and no state - fishy
00241       if((strcasecmp(request_state,"pending") != 0) && 
00242          (strcasecmp(request_state,"active") != 0)) break;
00243       if((time(NULL) - t_start) > request_timeout) break;
00244       if(result->retryDeltaTime < 5) result->retryDeltaTime=5;
00245       if(result->retryDeltaTime > 30) result->retryDeltaTime=30;
00246       sleep(result->retryDeltaTime);
00247       SRMv1Meth__getRequestStatusResponse r;
00248       if((soap_err=soap_call_SRMv1Meth__getRequestStatus(&soapobj,csoap->SOAP_URL(),
00249                "getRequestStatus",req.request_id(),r)) != SOAP_OK) {
00250         logger.msg(Arc::INFO, "SOAP request failed (getRequestStatus)");
00251         if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00252         csoap->disconnect();
00253         return SRM_ERROR_SOAP;
00254       };
00255       if(r._Result == NULL) {
00256         logger.msg(Arc::INFO, "SRM did not return any information");
00257         return SRM_ERROR_OTHER;
00258       };
00259       request_state = r._Result->state;
00260       result = r._Result;
00261     };
00262     if(file_ids.size() == 0) return SRM_ERROR_OTHER;
00263     req.file_ids(file_ids);
00264     return release(req);
00265   }
00266   
00267   SRMReturnCode SRM1Client::acquire(SRMClientRequest& req,std::list<std::string>& urls) {
00268     int soap_err = SOAP_OK;
00269     std::list<int> file_ids = req.file_ids();
00270     // Tell server to move files into "Running" state
00271     std::list<int>::iterator file_id = file_ids.begin();
00272     std::list<std::string>::iterator f_url = urls.begin();
00273     for(;file_id!=file_ids.end();) {
00274       SRMv1Meth__setFileStatusResponse r; r._Result=NULL;
00275       if((soap_err=soap_call_SRMv1Meth__setFileStatus(&soapobj,csoap->SOAP_URL(),
00276               "setFileStatus",req.request_id(),*file_id,"Running",r)) != SOAP_OK) {
00277         logger.msg(Arc::INFO, "SOAP request failed (setFileStatus)");
00278         if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00279         file_id=file_ids.erase(file_id); f_url=urls.erase(f_url);
00280         continue;
00281       };
00282       SRMv1Type__RequestStatus* result = r._Result;
00283       ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
00284       if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
00285         int n;
00286         for(n=0;n<fstatus->__size;n++) {
00287           SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
00288           if(!fs) continue;
00289           if(fs->fileId != *file_id) continue;
00290           if(fs->state && (strcasecmp(fs->state,"running") == 0)) {
00291             ++file_id; ++f_url; break;
00292           };
00293         };
00294         if(n<fstatus->__size) continue;
00295       };
00296       logger.msg(Arc::VERBOSE, "File could not be moved to Running state: %s", *f_url);
00297       file_id=file_ids.erase(file_id); f_url=urls.erase(f_url);
00298     };
00299     req.file_ids(file_ids);
00300     if(urls.size() == 0) return SRM_ERROR_OTHER;
00301     // Do not disconnect
00302     return SRM_OK;
00303   }
00304   
00305   SRMReturnCode SRM1Client::remove(SRMClientRequest& req) {
00306     SRMReturnCode rc = connect();
00307     if (rc != SRM_OK) return rc;
00308   
00309     SRMURL srmurl(req.surls().front().c_str());
00310     int soap_err = SOAP_OK;
00311     ArrayOfstring* SURLs = soap_new_ArrayOfstring(&soapobj,-1);
00312     if(!SURLs) {
00313       csoap->reset(); return SRM_ERROR_OTHER;
00314     };
00315     std::string file_url = srmurl.FullURL();
00316     const char* surl[] = { file_url.c_str() };
00317     SURLs->__ptr=(char**)surl;
00318     SURLs->__size=1;
00319     struct SRMv1Meth__advisoryDeleteResponse r;
00320     if((soap_err=soap_call_SRMv1Meth__advisoryDelete(&soapobj,csoap->SOAP_URL(),
00321                         "advisoryDelete",SURLs,r)) != SOAP_OK) {
00322       logger.msg(Arc::INFO, "SOAP request failed (SRMv1Meth__advisoryDelete)");
00323       if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00324       csoap->disconnect();
00325       return SRM_ERROR_SOAP;
00326     };
00327     return SRM_OK; 
00328   }
00329   
00330   SRMReturnCode SRM1Client::info(SRMClientRequest& req,
00331                                  std::list<struct SRMFileMetaData>& metadata,
00332                                  const int recursive,
00333                                  bool report_error) {
00334     SRMReturnCode rc = connect();
00335     if (rc != SRM_OK) return rc;
00336   
00337     SRMURL srmurl(req.surls().front().c_str());
00338     int soap_err = SOAP_OK;
00339     ArrayOfstring* SURLs = soap_new_ArrayOfstring(&soapobj,-1);
00340     if(!SURLs) {
00341       csoap->reset(); return SRM_ERROR_OTHER;
00342     };
00343     std::string file_url = srmurl.FullURL();
00344     const char* surl[] = { file_url.c_str() };
00345     SURLs->__ptr=(char**)surl;
00346     SURLs->__size=1;
00347     struct SRMv1Meth__getFileMetaDataResponse r; r._Result=NULL;
00348     if((soap_err=soap_call_SRMv1Meth__getFileMetaData(&soapobj,csoap->SOAP_URL(),
00349                         "getFileMetaData",SURLs,r)) != SOAP_OK) {
00350       logger.msg(Arc::INFO, "SOAP request failed (getFileMetaData)");
00351       if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00352       csoap->disconnect();
00353       return SRM_ERROR_SOAP;
00354     };
00355     if(r._Result == NULL) {
00356       if (report_error) logger.msg(Arc::INFO, "SRM did not return any information");
00357       else logger.msg(Arc::DEBUG, "SRM did not return any information");
00358       return SRM_ERROR_OTHER;
00359     };
00360     if((r._Result->__size == 0) || 
00361        (r._Result->__ptr == NULL) ||
00362        (r._Result->__ptr[0] == NULL)) {
00363       if (report_error) logger.msg(Arc::INFO, "SRM did not return any useful information");
00364       else logger.msg(Arc::DEBUG, "SRM did not return any useful information");
00365       return SRM_ERROR_OTHER;
00366     };
00367     SRMv1Type__FileMetaData& mdata = *(r._Result->__ptr[0]);
00368     struct SRMFileMetaData md;
00369     md.path=srmurl.FileName();
00370     // tidy up path
00371     std::string::size_type i = md.path.find("//", 0);
00372     while (i != std::string::npos) {
00373        md.path.erase(i, 1);
00374        i = md.path.find("//", 0);
00375     };
00376     if (md.path.find("/") != 0) md.path = "/" + md.path;
00377     // date, type and locality not supported in v1
00378     md.createdAtTime=0;
00379     md.fileType = SRM_FILE_TYPE_UNKNOWN;
00380     md.fileLocality = SRM_UNKNOWN;
00381     md.size=mdata.size;
00382     md.checkSumType="";
00383     md.checkSumValue="";
00384     if(mdata.checksumType) { md.checkSumType=mdata.checksumType; };
00385     if(mdata.checksumValue) { md.checkSumValue=mdata.checksumValue; };
00386     metadata.push_back(md);
00387     return SRM_OK; 
00388   }
00389   
00390   SRMReturnCode SRM1Client::release(SRMClientRequest& req) {
00391     SRMReturnCode rc = connect();
00392     if (rc != SRM_OK) return rc;
00393     int soap_err = SOAP_OK;
00394     std::list<int> file_ids = req.file_ids();
00395     // Tell server to move files into "Done" state
00396     std::list<int>::iterator file_id = file_ids.begin();
00397     for(;file_id!=file_ids.end();) {
00398       SRMv1Meth__setFileStatusResponse r; r._Result=NULL;
00399       if((soap_err=soap_call_SRMv1Meth__setFileStatus(&soapobj,csoap->SOAP_URL(),
00400               "setFileStatus",req.request_id(),*file_id,"Done",r)) != SOAP_OK) {
00401         logger.msg(Arc::INFO, "SOAP request failed (setFileStatus)");
00402         if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
00403         ++file_id; continue;
00404       };
00405       SRMv1Type__RequestStatus* result = r._Result;
00406       ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
00407       if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
00408         int n;
00409         for(n=0;n<fstatus->__size;n++) {
00410           SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
00411           if(fs->fileId != *file_id) continue;
00412           if(fs && fs->state && (strcasecmp(fs->state,"Done") == 0)) {
00413             file_id=file_ids.erase(file_id); break;
00414           };
00415         };
00416         if(n<fstatus->__size) continue;
00417       };
00418       logger.msg(Arc::VERBOSE, "File could not be moved to Done state");
00419       ++file_id;
00420     };
00421     req.file_ids(file_ids);
00422     return SRM_OK; 
00423   }
00424    
00425   SRMReturnCode SRM1Client::releaseGet(SRMClientRequest& req) {
00426     return release(req);
00427   }
00428   
00429   SRMReturnCode SRM1Client::releasePut(SRMClientRequest& req) {
00430     return release(req);
00431   }
00432   
00433   SRMReturnCode SRM1Client::abort(SRMClientRequest& req) {
00434     return release(req);
00435   }
00436   
00437 //} // namespace Arc