Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Static Public Member Functions | Protected Attributes | Static Protected Attributes | Private Member Functions
SRM1Client Class Reference

#include <SRM1Client.h>

Inheritance diagram for SRM1Client:
Inheritance graph
[legend]
Collaboration diagram for SRM1Client:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 SRM1Client (SRMURL url)
 ~SRM1Client (void)
SRMReturnCode ping (std::string &version, bool report_error=true)
 Find out the version supported by the server this client is connected to.
SRMReturnCode getSpaceTokens (std::list< std::string > &tokens, std::string description="")
 Find the space tokens available to write to which correspond to the space token description, if given.
SRMReturnCode getRequestTokens (std::list< std::string > &tokens, std::string description="")
 Returns a list of request tokens for the user calling the method which are still active requests, or the tokens corresponding to the token description, if given.
SRMReturnCode requestBringOnline (SRMClientRequest &req)
 Submit a request to bring online files.
SRMReturnCode requestBringOnlineStatus (SRMClientRequest &req)
 Query the status of a request to bring files online.
SRMReturnCode mkDir (SRMClientRequest &req)
 Make required directories for the SURL in the request.
SRMReturnCode getTURLs (SRMClientRequest &req, std::list< std::string > &urls)
 If the user wishes to copy a file from somewhere, getTURLs() is called to retrieve the transport URL to copy the file from.
SRMReturnCode putTURLs (SRMClientRequest &req, std::list< std::string > &urls, unsigned long long size=0)
 If the user wishes to copy a file to somewhere, putTURLs() is called to retrieve the transport URL to copy the file to.
SRMReturnCode releaseGet (SRMClientRequest &req)
 Should be called after a successful copy from SRM storage.
SRMReturnCode releasePut (SRMClientRequest &req)
 Should be called after a successful copy to SRM storage.
SRMReturnCode release (SRMClientRequest &req)
 Used in SRM v1 only.
SRMReturnCode abort (SRMClientRequest &req)
 Called in the case of failure during transfer or releasePut.
SRMReturnCode info (SRMClientRequest &req, std::list< struct SRMFileMetaData > &metadata, const int recursive=0, bool report_error=true)
 Returns information on a file or files (v2.2 and higher) stored in an SRM, such as file size, checksum and estimated access latency.
SRMReturnCode remove (SRMClientRequest &req)
 Delete a file physically from storage and the SRM namespace.
SRMReturnCode copy (SRMClientRequest &req, const std::string &source)
 Copy a file between two SRM storages.
SRMReturnCode connect (void)
 Establish a connection to the service.
bool disconnect (void)
 Disconnect from the service and destroy the connection.
void Timeout (int t)
 set the request timeout
std::string getVersion ()
 Returns the version of the SRM protocol used by this instance.
 operator bool (void)
bool operator! (void)

Static Public Member Functions

static SRMClientgetInstance (std::string url, bool &timedout, std::string utils_dir, time_t timeout=300)
 Returns an SRMClient instance with the required protocol version.

Protected Attributes

std::string service_endpoint
 The URL of the service endpoint, eg httpg://srm.ndgf.org:8443/srm/managerv2 All SURLs passed to methods must correspond to this endpoint.
Arc::HTTPSClientSOAPcsoap
 SOAP client object.
SRMImplementation implementation
 The implementation of the server.
std::string version
 The version of the SRM protocol used.

Static Protected Attributes

static time_t request_timeout = 300
 Timeout for requests to the SRM service.
static Arc::Logger logger
 Logger.

Private Member Functions

SRMReturnCode acquire (SRMClientRequest &req, std::list< std::string > &urls)

Detailed Description

Definition at line 21 of file SRM1Client.h.


Constructor & Destructor Documentation

Definition at line 7 of file SRM1Client.cpp.

                                   {
    version = "v1";
    implementation = SRM_IMPLEMENTATION_UNKNOWN;
    service_endpoint = url.ContactURL();
    csoap = new Arc::HTTPSClientSOAP(service_endpoint.c_str(),&soapobj,url.GSSAPI(),request_timeout,false);
    if(!csoap) { csoap=NULL; return; };
    if(!*csoap) { delete csoap; csoap=NULL; return; };
    soapobj.namespaces=srm1_soap_namespaces;
  }

Here is the call graph for this function:

Definition at line 17 of file SRM1Client.cpp.

                              {
    if(csoap) { csoap->disconnect(); delete csoap; };
  }

Here is the call graph for this function:


Member Function Documentation

Called in the case of failure during transfer or releasePut.

Releases all TURLs involved in the transfer.

Parameters:
reqThe request object
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 433 of file SRM1Client.cpp.

                                                       {
    return release(req);
  }

Here is the call graph for this function:

SRMReturnCode SRM1Client::acquire ( SRMClientRequest req,
std::list< std::string > &  urls 
) [private]

Definition at line 267 of file SRM1Client.cpp.

                                                                                  {
    int soap_err = SOAP_OK;
    std::list<int> file_ids = req.file_ids();
    // Tell server to move files into "Running" state
    std::list<int>::iterator file_id = file_ids.begin();
    std::list<std::string>::iterator f_url = urls.begin();
    for(;file_id!=file_ids.end();) {
      SRMv1Meth__setFileStatusResponse r; r._Result=NULL;
      if((soap_err=soap_call_SRMv1Meth__setFileStatus(&soapobj,csoap->SOAP_URL(),
              "setFileStatus",req.request_id(),*file_id,"Running",r)) != SOAP_OK) {
        logger.msg(Arc::INFO, "SOAP request failed (setFileStatus)");
        if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
        file_id=file_ids.erase(file_id); f_url=urls.erase(f_url);
        continue;
      };
      SRMv1Type__RequestStatus* result = r._Result;
      ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
      if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
        int n;
        for(n=0;n<fstatus->__size;n++) {
          SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
          if(!fs) continue;
          if(fs->fileId != *file_id) continue;
          if(fs->state && (strcasecmp(fs->state,"running") == 0)) {
            ++file_id; ++f_url; break;
          };
        };
        if(n<fstatus->__size) continue;
      };
      logger.msg(Arc::VERBOSE, "File could not be moved to Running state: %s", *f_url);
      file_id=file_ids.erase(file_id); f_url=urls.erase(f_url);
    };
    req.file_ids(file_ids);
    if(urls.size() == 0) return SRM_ERROR_OTHER;
    // Do not disconnect
    return SRM_OK;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

SRMReturnCode SRMClient::connect ( void  ) [inherited]

Establish a connection to the service.

Returns:
SRMReturnCode specifying outcome of operation

Definition at line 14 of file SRMClient.cpp.

                                       {
    if(!csoap) return SRM_ERROR_OTHER;
    int r = csoap->connect();
    if (r == 1) return SRM_ERROR_TEMPORARY;
    if (r != 0) return SRM_ERROR_CONNECTION;
    return SRM_OK;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

SRMReturnCode SRM1Client::copy ( SRMClientRequest req,
const std::string &  source 
) [virtual]

Copy a file between two SRM storages.

Parameters:
reqThe request object
sourceThe source SURL
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 189 of file SRM1Client.cpp.

                                                          {
    SRMReturnCode rc = connect();
    if (rc != SRM_OK) return rc;
  
    SRMURL srmurl(req.surls().front().c_str());
    int soap_err = SOAP_OK;
    std::list<int> file_ids;
    // Request place for new file to put
    ArrayOfstring* src_file_names = soap_new_ArrayOfstring(&soapobj,-1);
    ArrayOfstring* dst_file_names = soap_new_ArrayOfstring(&soapobj,-1);
    ArrayOfboolean* bools = soap_new_ArrayOfboolean(&soapobj,-1);
    struct SRMv1Meth__copyResponse r; r._Result=NULL;
    if((!src_file_names) || (!dst_file_names)) {
      csoap->reset(); return SRM_ERROR_OTHER;
    };
    std::string file_url = srmurl.FullURL();
    const char* surl[] = { file_url.c_str() };
    const char* srcurl[] = { source.c_str() };
    bool bools_[] = { false };
    src_file_names->__ptr=(char**)srcurl; src_file_names->__size=1;
    dst_file_names->__ptr=(char**)surl; dst_file_names->__size=1;
    bools->__ptr=bools_; bools->__size=1;
    if((soap_err=soap_call_SRMv1Meth__copy(&soapobj,csoap->SOAP_URL(),"copy",
                 src_file_names,dst_file_names,bools,r)) != SOAP_OK) {
      logger.msg(Arc::INFO, "SOAP request failed (copy)");
      if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
      csoap->disconnect();
      return SRM_ERROR_SOAP;
    };
    if(r._Result == NULL) {
      logger.msg(Arc::INFO, "SRM did not return any information");
      return SRM_ERROR_OTHER;
    };
    char* request_state = r._Result->state;
    req.request_id(r._Result->requestId);
    SRMv1Type__RequestStatus* result = r._Result;
    time_t t_start = time(NULL);
    // Ask for request state in loop till SRM server returns
    // request status !Pending and file status Ready
    for(;;) {
      ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
      if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
        for(int n=0;n<fstatus->__size;n++) {
          SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
          if(fs && fs->state && (strcasecmp(fs->state,"ready") == 0)) {
            file_ids.push_back(fs->fileId);
          };
        };
      };
      if(file_ids.size()) break; // Have requested data
      if(!request_state) break; // No data and no state - fishy
      if((strcasecmp(request_state,"pending") != 0) && 
         (strcasecmp(request_state,"active") != 0)) break;
      if((time(NULL) - t_start) > request_timeout) break;
      if(result->retryDeltaTime < 5) result->retryDeltaTime=5;
      if(result->retryDeltaTime > 30) result->retryDeltaTime=30;
      sleep(result->retryDeltaTime);
      SRMv1Meth__getRequestStatusResponse r;
      if((soap_err=soap_call_SRMv1Meth__getRequestStatus(&soapobj,csoap->SOAP_URL(),
               "getRequestStatus",req.request_id(),r)) != SOAP_OK) {
        logger.msg(Arc::INFO, "SOAP request failed (getRequestStatus)");
        if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
        csoap->disconnect();
        return SRM_ERROR_SOAP;
      };
      if(r._Result == NULL) {
        logger.msg(Arc::INFO, "SRM did not return any information");
        return SRM_ERROR_OTHER;
      };
      request_state = r._Result->state;
      result = r._Result;
    };
    if(file_ids.size() == 0) return SRM_ERROR_OTHER;
    req.file_ids(file_ids);
    return release(req);
  }

Here is the call graph for this function:

bool SRMClient::disconnect ( void  ) [inline, inherited]

Disconnect from the service and destroy the connection.

Definition at line 340 of file SRMClient.h.

{ if(!csoap) return true; return (csoap->disconnect() == 0);};

Here is the call graph for this function:

Here is the caller graph for this function:

SRMClient * SRMClient::getInstance ( std::string  url,
bool &  timedout,
std::string  utils_dir,
time_t  timeout = 300 
) [static, inherited]

Returns an SRMClient instance with the required protocol version.

This must be used to create SRMClient instances. Specifying a version explicitly forces creation of a client with that version.

Parameters:
urlA SURL. A client connects to the service host derived from this SURL. All operations with a client instance must use SURLs with the same host as this one.
timedoutWhether the connection timed out
utils_dirPath to a directory contining files with SRM info
timeoutConnection timeout. is returned.

Definition at line 22 of file SRMClient.cpp.

                                                    {
    request_timeout = timeout;
    SRMURL srm_url(url);
    if (!srm_url) return NULL;
  
    // can't use ping with srmv1 so just return
    if (srm_url.SRMVersion() == SRMURL::SRM_URL_VERSION_1)
      return new SRM1Client(srm_url);
  
    if (utils_dir.empty()) {
      if (srm_url.SRMVersion() == SRMURL::SRM_URL_VERSION_2_2) return new SRM22Client(srm_url);
      return NULL;
    }
      
    SRMReturnCode srm_error;
    std::string version;
  
    SRMInfo info(utils_dir);
    SRMFileInfo srm_file_info;
    // lists of ports and protocols in the order to try them
    std::vector<int> ports;
    ports.push_back(srm_url.Port());
    if (srm_url.Port() != 8443) ports.push_back(8443);
    if (srm_url.Port() != 8446) ports.push_back(8446);
    if (srm_url.Port() != 8444) ports.push_back(8444);
    std::vector<std::string> protocols;
    if (srm_url.GSSAPI()) {
      protocols.push_back("gssapi");
      protocols.push_back("gsi");
    }
    else {
      protocols.push_back("gsi");
      protocols.push_back("gssapi");
    }    
    
    srm_file_info.host = srm_url.Host();
    srm_file_info.version = srm_url.SRMVersion();
    
    // no info
    if (!info.getSRMFileInfo(srm_file_info)) {
      for (std::vector<std::string>::iterator protocol = protocols.begin(); protocol != protocols.end(); protocol++) {
        srm_url.GSSAPI((*protocol == "gssapi") ? true : false);
        for (std::vector<int>::iterator port = ports.begin(); port != ports.end(); port++) {
          logger.msg(Arc::VERBOSE, "Attempting to contact %s on port %i using protocol %s", srm_url.Host(), *port, *protocol);
          srm_url.SetPort(*port);
          SRMClient * client = new SRM22Client(srm_url);
      
          if ((srm_error = client->ping(version, false)) == SRM_OK) {
            srm_file_info.port = *port;
            srm_file_info.protocol = *protocol;
            logger.msg(Arc::VERBOSE, "Storing port %i and protocol %s for %s", *port, *protocol, srm_url.Host());
            info.putSRMFileInfo(srm_file_info);
            return client;
          }
          delete client;
          if (srm_error == SRM_ERROR_TEMPORARY) {
            // probably correct port and protocol and service is down
            // but don't want to risk storing incorrect info
            timedout = true;
            return NULL;
          }
        }
      }
      // if we get here no combination has worked
      logger.msg(Arc::VERBOSE, "No combination of port and protocol succeeded for %s", srm_url.Host());
      return NULL;
    }
    // url agrees with file info
    else if (srm_file_info == srm_url) {
      srm_url.SetPort(srm_file_info.port);
      srm_url.GSSAPI((srm_file_info.protocol == "gssapi") ? true : false);
      return new SRM22Client(srm_url);
    }
    // url disagrees with file info
    else {
      // ping and if ok, replace file info
      logger.msg(Arc::VERBOSE, "URL %s disagrees with stored SRM info, testing new info", srm_url.ShortURL());
      SRMClient * client = new SRM22Client(srm_url);
  
      if ((srm_error = client->ping(version, false)) == SRM_OK) {
        srm_file_info.port = srm_url.Port();
        srm_file_info.protocol = srm_url.GSSAPI()? "gssapi" : "gsi";
        logger.msg(Arc::VERBOSE, "Replacing old SRM info with new for URL %s", srm_url.ShortURL());
        info.putSRMFileInfo(srm_file_info);
        return client;
      }
      delete client;
      if (srm_error == SRM_ERROR_TEMPORARY) {
        // probably correct port and protocol and service is down
        // but don't want to risk storing incorrect info
        timedout = true;
      }
      return NULL;
    }
 }

Here is the call graph for this function:

Here is the caller graph for this function:

SRMReturnCode SRM1Client::getRequestTokens ( std::list< std::string > &  tokens,
std::string  description = "" 
) [inline, virtual]

Returns a list of request tokens for the user calling the method which are still active requests, or the tokens corresponding to the token description, if given.

Parameters:
tokensThe list filled by the service
descriptionThe user request description, which can be specified when the request is created
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 40 of file SRM1Client.h.

SRMReturnCode SRM1Client::getSpaceTokens ( std::list< std::string > &  tokens,
std::string  description = "" 
) [inline, virtual]

Find the space tokens available to write to which correspond to the space token description, if given.

The list of tokens is a list of numbers referring to the SRM internal definition of the spaces, not user-readable strings.

Parameters:
tokensThe list filled by the service
descriptionThe space token description
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 36 of file SRM1Client.h.

SRMReturnCode SRM1Client::getTURLs ( SRMClientRequest req,
std::list< std::string > &  urls 
) [virtual]

If the user wishes to copy a file from somewhere, getTURLs() is called to retrieve the transport URL to copy the file from.

Parameters:
reqThe request object
urlsA list of TURLs filled by the method
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 25 of file SRM1Client.cpp.

                                                               {
    SRMReturnCode rc = connect();
    if (rc != SRM_OK) return rc;

    SRMURL srmurl(req.surls().front().c_str());
    int soap_err = SOAP_OK;
    std::list<int> file_ids;
    ArrayOfstring* SURLs = soap_new_ArrayOfstring(&soapobj,-1);
    ArrayOfstring* Protocols = soap_new_ArrayOfstring(&soapobj,-1);
    struct SRMv1Meth__getResponse r; r._Result=NULL;
    if((!SURLs) || (!Protocols)) {
      csoap->reset(); return SRM_ERROR_OTHER;
    };
    Protocols->__ptr=(char**)Supported_Protocols;
    Protocols->__size=sizeof(Supported_Protocols)/sizeof(Supported_Protocols[0]);
    std::string file_url = srmurl.FullURL();
    const char* surl[] = { file_url.c_str() };
    SURLs->__ptr=(char**)surl;
    SURLs->__size=1;
    if((soap_err=soap_call_SRMv1Meth__get(&soapobj,csoap->SOAP_URL(),"get",SURLs,Protocols,r)) != SOAP_OK) {
      logger.msg(Arc::INFO, "SOAP request failed (get)");
      if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
      csoap->disconnect();
      return SRM_ERROR_SOAP;
    };
    if(r._Result == NULL) {  
      logger.msg(Arc::INFO, "SRM did not return any information");
      return SRM_ERROR_OTHER;
    };
    char* request_state = r._Result->state;
    req.request_id(r._Result->requestId);
    SRMv1Type__RequestStatus& result = *(r._Result);
    time_t t_start = time(NULL);
    for(;;) {
      ArrayOfRequestFileStatus* fstatus = result.fileStatuses;
      if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
        for(int n=0;n<fstatus->__size;n++) {
          SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
          if(fs && fs->state && (strcasecmp(fs->state,"ready") == 0)) {
            if(fs->TURL) {
              urls.push_back(std::string(fs->TURL));
              file_ids.push_back(fs->fileId);
            };
          };
        };
      };
      if(urls.size()) break; // Have requested data
      if(!request_state) break; // No data and no state - fishy
      if(strcasecmp(request_state,"pending") != 0) break;
      if((time(NULL) - t_start) > request_timeout) break;
      if(result.retryDeltaTime < 1) result.retryDeltaTime=1;
      if(result.retryDeltaTime > 10) result.retryDeltaTime=10;
      sleep(result.retryDeltaTime);
      SRMv1Meth__getRequestStatusResponse r;
      if((soap_err=soap_call_SRMv1Meth__getRequestStatus(&soapobj,csoap->SOAP_URL(),
               "getRequestStatus",req.request_id(),r)) != SOAP_OK) {
        logger.msg(Arc::INFO, "SOAP request failed (getRequestStatus)");
        if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
        csoap->disconnect();
        return SRM_ERROR_SOAP;
      };
      if(r._Result == NULL) {  
        logger.msg(Arc::INFO, "SRM did not return any information");
        return SRM_ERROR_OTHER;
      };
      request_state = r._Result->state;
      result = *(r._Result);
    };
    req.file_ids(file_ids);
    if(urls.size() == 0) return SRM_ERROR_OTHER;
    return acquire(req,urls);
  }

Here is the call graph for this function:

std::string SRMClient::getVersion ( ) [inline, inherited]

Returns the version of the SRM protocol used by this instance.

Definition at line 371 of file SRMClient.h.

{return version;};

Here is the caller graph for this function:

SRMReturnCode SRM1Client::info ( SRMClientRequest req,
std::list< struct SRMFileMetaData > &  metadata,
const int  recursive = 0,
bool  report_error = true 
) [virtual]

Returns information on a file or files (v2.2 and higher) stored in an SRM, such as file size, checksum and estimated access latency.

Parameters:
reqThe request object
metadataA list of structs filled with file information
recursiveThe level of recursion into sub directories
report_errorDetermines if errors should be reported
Returns:
SRMReturnCode specifying outcome of operation
See also:
SRMFileMetaData

Implements SRMClient.

Definition at line 330 of file SRM1Client.cpp.

                                                    {
    SRMReturnCode rc = connect();
    if (rc != SRM_OK) return rc;
  
    SRMURL srmurl(req.surls().front().c_str());
    int soap_err = SOAP_OK;
    ArrayOfstring* SURLs = soap_new_ArrayOfstring(&soapobj,-1);
    if(!SURLs) {
      csoap->reset(); return SRM_ERROR_OTHER;
    };
    std::string file_url = srmurl.FullURL();
    const char* surl[] = { file_url.c_str() };
    SURLs->__ptr=(char**)surl;
    SURLs->__size=1;
    struct SRMv1Meth__getFileMetaDataResponse r; r._Result=NULL;
    if((soap_err=soap_call_SRMv1Meth__getFileMetaData(&soapobj,csoap->SOAP_URL(),
                        "getFileMetaData",SURLs,r)) != SOAP_OK) {
      logger.msg(Arc::INFO, "SOAP request failed (getFileMetaData)");
      if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
      csoap->disconnect();
      return SRM_ERROR_SOAP;
    };
    if(r._Result == NULL) {
      if (report_error) logger.msg(Arc::INFO, "SRM did not return any information");
      else logger.msg(Arc::DEBUG, "SRM did not return any information");
      return SRM_ERROR_OTHER;
    };
    if((r._Result->__size == 0) || 
       (r._Result->__ptr == NULL) ||
       (r._Result->__ptr[0] == NULL)) {
      if (report_error) logger.msg(Arc::INFO, "SRM did not return any useful information");
      else logger.msg(Arc::DEBUG, "SRM did not return any useful information");
      return SRM_ERROR_OTHER;
    };
    SRMv1Type__FileMetaData& mdata = *(r._Result->__ptr[0]);
    struct SRMFileMetaData md;
    md.path=srmurl.FileName();
    // tidy up path
    std::string::size_type i = md.path.find("//", 0);
    while (i != std::string::npos) {
       md.path.erase(i, 1);
       i = md.path.find("//", 0);
    };
    if (md.path.find("/") != 0) md.path = "/" + md.path;
    // date, type and locality not supported in v1
    md.createdAtTime=0;
    md.fileType = SRM_FILE_TYPE_UNKNOWN;
    md.fileLocality = SRM_UNKNOWN;
    md.size=mdata.size;
    md.checkSumType="";
    md.checkSumValue="";
    if(mdata.checksumType) { md.checkSumType=mdata.checksumType; };
    if(mdata.checksumValue) { md.checkSumValue=mdata.checksumValue; };
    metadata.push_back(md);
    return SRM_OK; 
  }

Here is the call graph for this function:

SRMReturnCode SRM1Client::mkDir ( SRMClientRequest req) [inline, virtual]

Make required directories for the SURL in the request.

Parameters:
reqThe request object
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 48 of file SRM1Client.h.

SRMClient::operator bool ( void  ) [inline, inherited]

Definition at line 519 of file SRMClient.h.

{ return csoap; };
bool SRMClient::operator! ( void  ) [inline, inherited]

Definition at line 520 of file SRMClient.h.

{ return !csoap; };
SRMReturnCode SRM1Client::ping ( std::string &  version,
bool  report_error = true 
) [inline, virtual]

Find out the version supported by the server this client is connected to.

Since this method is used to determine which client version to instantiate, we may not want to report an error to the user, so setting report_error to false supresses the error message.

Parameters:
versionThe version returned by the server
report_errorWhether an error should be reported
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 32 of file SRM1Client.h.

SRMReturnCode SRM1Client::putTURLs ( SRMClientRequest req,
std::list< std::string > &  urls,
unsigned long long  size = 0 
) [virtual]

If the user wishes to copy a file to somewhere, putTURLs() is called to retrieve the transport URL to copy the file to.

Parameters:
reqThe request object
urlsA list of TURLs filled by the method
sizeThe size of the file
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 99 of file SRM1Client.cpp.

                                                              {
    SRMReturnCode rc = connect();
    if (rc != SRM_OK) return rc;
  
    SRMURL srmurl(req.surls().front().c_str());
    int soap_err = SOAP_OK;
    std::list<int> file_ids;
    // Request place for new file to put
    ArrayOfstring* src_file_names = soap_new_ArrayOfstring(&soapobj,-1);
    ArrayOfstring* dst_file_names = soap_new_ArrayOfstring(&soapobj,-1);
    ArrayOflong* sizes = soap_new_ArrayOflong(&soapobj,-1);
    ArrayOfboolean* wantPermanent = soap_new_ArrayOfboolean(&soapobj,-1);
    ArrayOfstring* protocols = soap_new_ArrayOfstring(&soapobj,-1);
    struct SRMv1Meth__putResponse r; r._Result=NULL;
    //r._Result=soap_new_SRMv1Type__RequestStatus(&soapobj,-1);
    if((!src_file_names) || (!dst_file_names) || (!sizes) || 
       (!wantPermanent) || (!protocols)) {
      csoap->reset(); return SRM_ERROR_OTHER;
    };
    protocols->__ptr=(char**)Supported_Protocols;
    protocols->__size=sizeof(Supported_Protocols)/sizeof(Supported_Protocols[0]);
    LONG64 sizes_[] = { size }; // TODO
    bool wantPermanent_[] = { true };
    std::string file_url = srmurl.FullURL();
    const char* surl[] = { file_url.c_str() };
    src_file_names->__ptr=(char**)surl; src_file_names->__size=1;
    dst_file_names->__ptr=(char**)surl; dst_file_names->__size=1;
    sizes->__ptr=sizes_; sizes->__size=1;
    wantPermanent->__ptr=wantPermanent_; wantPermanent->__size=1;
    if((soap_err=soap_call_SRMv1Meth__put(&soapobj,csoap->SOAP_URL(),"put",
                 src_file_names,dst_file_names,sizes,
                 wantPermanent,protocols,r)) != SOAP_OK) {
      logger.msg(Arc::INFO, "SOAP request failed (put)");
      if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
      csoap->disconnect();
      return SRM_ERROR_SOAP;
    };
    if(r._Result == NULL) {
      logger.msg(Arc::INFO, "SRM did not return any information");
      return SRM_ERROR_OTHER;
    };
    char* request_state = r._Result->state;
    req.request_id(r._Result->requestId);
    SRMv1Type__RequestStatus* result = r._Result;
    time_t t_start = time(NULL);
    // Ask for request state in loop till SRM server returns  
    // request status !Pending and file status ready
    for(;;) {
      ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
      if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
        for(int n=0;n<fstatus->__size;n++) {
          SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
          if(fs && fs->state && (strcasecmp(fs->state,"ready") == 0)) {
            if(fs->TURL) {
              urls.push_back(std::string(fs->TURL));
              file_ids.push_back(fs->fileId);
            };
          };
        };
      };
      if(urls.size()) break; // Have requested data
      if(!request_state) break; // No data and no state - fishy
      // Leave if state is not pending and no endpoints 
      if(strcasecmp(request_state,"pending") != 0) break;
      if((time(NULL) - t_start) > request_timeout) break;
      if(result->retryDeltaTime < 1) result->retryDeltaTime=1;
      if(result->retryDeltaTime > 10) result->retryDeltaTime=10;
      sleep(result->retryDeltaTime);
      SRMv1Meth__getRequestStatusResponse r;
      if((soap_err=soap_call_SRMv1Meth__getRequestStatus(&soapobj,csoap->SOAP_URL(),
               "getRequestStatus",req.request_id(),r)) != SOAP_OK) {
        logger.msg(Arc::INFO, "SOAP request failed (getRequestStatus)");
        if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
        csoap->disconnect();
        return SRM_ERROR_SOAP;
      };
      if(r._Result == NULL) {
        logger.msg(Arc::INFO, "SRM did not return any information");
        return SRM_ERROR_OTHER;
      };
      request_state = r._Result->state;
      result = r._Result;
    };
    req.file_ids(file_ids);
    if(urls.size() == 0) return SRM_ERROR_OTHER;
    return acquire(req,urls);
  }

Here is the call graph for this function:

Used in SRM v1 only.

Called to release files after successful transfer.

Parameters:
reqThe request object
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 390 of file SRM1Client.cpp.

                                                         {
    SRMReturnCode rc = connect();
    if (rc != SRM_OK) return rc;
    int soap_err = SOAP_OK;
    std::list<int> file_ids = req.file_ids();
    // Tell server to move files into "Done" state
    std::list<int>::iterator file_id = file_ids.begin();
    for(;file_id!=file_ids.end();) {
      SRMv1Meth__setFileStatusResponse r; r._Result=NULL;
      if((soap_err=soap_call_SRMv1Meth__setFileStatus(&soapobj,csoap->SOAP_URL(),
              "setFileStatus",req.request_id(),*file_id,"Done",r)) != SOAP_OK) {
        logger.msg(Arc::INFO, "SOAP request failed (setFileStatus)");
        if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
        ++file_id; continue;
      };
      SRMv1Type__RequestStatus* result = r._Result;
      ArrayOfRequestFileStatus* fstatus = result->fileStatuses;
      if(fstatus && (fstatus->__size) && (fstatus->__ptr)) {
        int n;
        for(n=0;n<fstatus->__size;n++) {
          SRMv1Type__RequestFileStatus* fs = fstatus->__ptr[n];
          if(fs->fileId != *file_id) continue;
          if(fs && fs->state && (strcasecmp(fs->state,"Done") == 0)) {
            file_id=file_ids.erase(file_id); break;
          };
        };
        if(n<fstatus->__size) continue;
      };
      logger.msg(Arc::VERBOSE, "File could not be moved to Done state");
      ++file_id;
    };
    req.file_ids(file_ids);
    return SRM_OK; 
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Should be called after a successful copy from SRM storage.

Parameters:
reqThe request object
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 425 of file SRM1Client.cpp.

                                                            {
    return release(req);
  }

Here is the call graph for this function:

Should be called after a successful copy to SRM storage.

Parameters:
reqThe request object
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 429 of file SRM1Client.cpp.

                                                            {
    return release(req);
  }

Here is the call graph for this function:

Delete a file physically from storage and the SRM namespace.

Parameters:
reqThe request object
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 305 of file SRM1Client.cpp.

                                                        {
    SRMReturnCode rc = connect();
    if (rc != SRM_OK) return rc;
  
    SRMURL srmurl(req.surls().front().c_str());
    int soap_err = SOAP_OK;
    ArrayOfstring* SURLs = soap_new_ArrayOfstring(&soapobj,-1);
    if(!SURLs) {
      csoap->reset(); return SRM_ERROR_OTHER;
    };
    std::string file_url = srmurl.FullURL();
    const char* surl[] = { file_url.c_str() };
    SURLs->__ptr=(char**)surl;
    SURLs->__size=1;
    struct SRMv1Meth__advisoryDeleteResponse r;
    if((soap_err=soap_call_SRMv1Meth__advisoryDelete(&soapobj,csoap->SOAP_URL(),
                        "advisoryDelete",SURLs,r)) != SOAP_OK) {
      logger.msg(Arc::INFO, "SOAP request failed (SRMv1Meth__advisoryDelete)");
      if(logger.getThreshold() > Arc::FATAL) soap_print_fault(&soapobj, stderr);
      csoap->disconnect();
      return SRM_ERROR_SOAP;
    };
    return SRM_OK; 
  }

Here is the call graph for this function:

Submit a request to bring online files.

This operation is asynchronous and the status of the request can be checked by calling requestBringOnlineStatus() with the request token in req which is assigned by this method.

Parameters:
reqThe request object
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 44 of file SRM1Client.h.

Query the status of a request to bring files online.

The SURLs map is updated if the status of any files in the request has changed.

Parameters:
reqThe request object to query the status of
Returns:
SRMReturnCode specifying outcome of operation

Implements SRMClient.

Definition at line 46 of file SRM1Client.h.

void SRMClient::Timeout ( int  t) [inline, inherited]

set the request timeout

Definition at line 366 of file SRMClient.h.


Member Data Documentation

Arc::HTTPSClientSOAP* SRMClient::csoap [protected, inherited]

SOAP client object.

Definition at line 307 of file SRMClient.h.

The implementation of the server.

Definition at line 312 of file SRMClient.h.

Arc::Logger SRMClient::logger [static, protected, inherited]

Logger.

Definition at line 327 of file SRMClient.h.

time_t SRMClient::request_timeout = 300 [static, protected, inherited]

Timeout for requests to the SRM service.

Definition at line 317 of file SRMClient.h.

std::string SRMClient::service_endpoint [protected, inherited]

The URL of the service endpoint, eg httpg://srm.ndgf.org:8443/srm/managerv2 All SURLs passed to methods must correspond to this endpoint.

Definition at line 302 of file SRMClient.h.

std::string SRMClient::version [protected, inherited]

The version of the SRM protocol used.

Definition at line 322 of file SRMClient.h.


The documentation for this class was generated from the following files: