Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
Arc::CREAMClient Class Reference

#include <CREAMClient.h>

Collaboration diagram for Arc::CREAMClient:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 CREAMClient (const URL &url, const MCCConfig &cfg, int timeout)
 ~CREAMClient ()
void setDelegationId (const std::string &delegId)
bool createDelegation (const std::string &delegation_id, const std::string &proxy)
bool destroyDelegation (const std::string &delegation_id)
bool registerJob (const std::string &jdl_text, creamJobInfo &info)
bool startJob (const std::string &jobid)
bool stat (const std::string &jobid, Job &job)
bool cancel (const std::string &jobid)
bool purge (const std::string &jobid)

Private Member Functions

bool process (PayloadSOAP &req, XMLNode &response)

Private Attributes

std::string action
ClientSOAPclient
std::string cafile
std::string cadir
NS cream_ns
std::string delegationId

Static Private Attributes

static Logger logger

Detailed Description

Definition at line 26 of file CREAMClient.h.


Constructor & Destructor Documentation

Arc::CREAMClient::CREAMClient ( const URL url,
const MCCConfig cfg,
int  timeout 
)

Definition at line 94 of file CREAMClient.cpp.

    : client(NULL),
      cafile(cfg.cafile),
      cadir(cfg.cadir) {
    logger.msg(INFO, "Creating a CREAM client");
    client = new ClientSOAP(cfg, url, timeout);
    if (!client)
      logger.msg(VERBOSE, "Unable to create SOAP client used by CREAMClient.");
    set_cream_namespaces(cream_ns);
  }

Here is the call graph for this function:

Definition at line 105 of file CREAMClient.cpp.

                            {
    if (client)
      delete client;
  }

Member Function Documentation

bool Arc::CREAMClient::cancel ( const std::string &  jobid)

Definition at line 317 of file CREAMClient.cpp.

                                                 {
    logger.msg(VERBOSE, "Creating and sending request to terminate a job");

    action = "JobCancel";

    PayloadSOAP req(cream_ns);
    req.NewChild("types:J" + action + "Request").NewChild("types:jobId").NewChild("types:id") = jobid;

    XMLNode response;
    if (!process(req, response))
      return false;

    if (!response) {
      logger.msg(VERBOSE, "Empty response");
      return false;
    }

    return true;
  }

Here is the call graph for this function:

bool Arc::CREAMClient::createDelegation ( const std::string &  delegation_id,
const std::string &  proxy 
)

Definition at line 425 of file CREAMClient.cpp.

                                                             {
    logger.msg(VERBOSE, "Creating delegation");

    action = "getProxyReq";

    PayloadSOAP req(cream_ns);
    req.NewChild("deleg:" + action).NewChild("delegationID") = delegation_id;

    XMLNode response;
    if (!process(req, response))
      return false;

    std::string proxyRequestStr = (std::string)response["getProxyReqReturn"];
    if (proxyRequestStr.empty()) {
      logger.msg(VERBOSE, "Malformed response: missing getProxyReqReturn");
      return false;
    }

    //Sign the proxy certificate
    Credential signer(proxy, "", cadir, cafile);
    std::string signedCert;
    // TODO: Hardcoded time shift - VERY BAD approach
    Time start_time = Time() - Period(300);
    Time end_time = signer.GetEndTime();
    if(end_time < start_time) {
      logger.msg(VERBOSE, "Delegatable credentials expired: %s",end_time.str());
      return false;
    }
    // CREAM is picky about end time of delegated credentials, so
    // make sure it does not exceed end time of signer
    Credential proxy_cred(start_time,end_time-start_time);
    proxy_cred.InquireRequest(proxyRequestStr);
    proxy_cred.SetProxyPolicy("gsi2", "", "", -1);

    if (!(signer.SignRequest(&proxy_cred, signedCert))) {
      logger.msg(VERBOSE, "Failed signing certificate request");
      return false;
    }

    std::string signedOutputCert, signedOutputCertChain;
    signer.OutputCertificate(signedOutputCert);
    signer.OutputCertificateChain(signedOutputCertChain);
    signedCert.append(signedOutputCert).append(signedOutputCertChain);

    action = "putProxy";
    req = PayloadSOAP(cream_ns);
    XMLNode putProxyRequest = req.NewChild("deleg:" + action);
    putProxyRequest.NewChild("delegationID") = delegation_id;
    putProxyRequest.NewChild("proxy") = signedCert;

    response = XMLNode();
    if (!process(req, response))
      return false;

    if (!response) {
      logger.msg(VERBOSE, "Failed putting signed delegation certificate to service");
      return false;
    }

    return true;
  }

Here is the call graph for this function:

bool Arc::CREAMClient::destroyDelegation ( const std::string &  delegation_id)

Definition at line 488 of file CREAMClient.cpp.

                                                                    {
    logger.msg(VERBOSE, "Creating delegation");

    action = "destroy";

    PayloadSOAP req(cream_ns);
    req.NewChild("deleg:" + action).NewChild("delegationID") = delegation_id;

    XMLNode response;
    if (!process(req, response))
      return false;

    if (!response) {
      logger.msg(VERBOSE, "Empty response");
      return false;
    }

    return true;
  }

Here is the call graph for this function:

bool Arc::CREAMClient::process ( PayloadSOAP req,
XMLNode response 
) [private]

Definition at line 110 of file CREAMClient.cpp.

                                                               {
    if (!client) {
      logger.msg(VERBOSE, "CREAMClient not created properly");
      return false;
    }

    PayloadSOAP *resp = NULL;
    if (!client->process("http://glite.org/2007/11/ce/cream/" + action, &req, &resp)) {
      logger.msg(VERBOSE, "%s request failed", action);
      return false;
    }

    if (resp == NULL) {
      logger.msg(VERBOSE, "There was no SOAP response");
      return false;
    }

    if ((*resp)[action + "Response"]["result"])
      (*resp)[action + "Response"]["result"].New(response);
    else
      (*resp)[action + "Response"].New(response);

    delete resp;

    if (!response) {
      logger.msg(VERBOSE, "Empty response");
      return false;
    }

    XMLNode fault;
    if (response["JobUnknownFault"])
      fault = response["JobUnknownFault"];
    if (response["JobStatusInvalidFault"])
      fault = response["JobStatusInvalidFault"];
    if (response["DelegationIdMismatchFault"])
      fault = response["DelegationIdMismatchFault"];
    if (response["DateMismatchFault"])
      fault = response["DateMismatchFault"];
    if (response["LeaseIdMismatchFault"])
      fault = response["LeaseIdMismatchFault"];
    if (response["GenericFault"])
      response["GenericFault"];

    if (fault) {
      logger.msg(VERBOSE, "Request failed: %s", (std::string)(fault["Description"]));
      return false;
    }

    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::CREAMClient::purge ( const std::string &  jobid)

Definition at line 337 of file CREAMClient.cpp.

                                                {
    logger.msg(VERBOSE, "Creating and sending request to clean a job");

    action = "JobPurge";

    PayloadSOAP req(cream_ns);
    req.NewChild("types:" + action + "Request").NewChild("types:jobId").NewChild("types:id") = jobid;

    XMLNode response;
    if (!process(req, response))
      return false;

    if (!response) {
      logger.msg(VERBOSE, "Empty response");
      return false;
    }

    return true;
  }

Here is the call graph for this function:

bool Arc::CREAMClient::registerJob ( const std::string &  jdl_text,
creamJobInfo info 
)

Definition at line 357 of file CREAMClient.cpp.

                                                    {
    logger.msg(VERBOSE, "Creating and sending job register request");

    action = "JobRegister";

    PayloadSOAP req(cream_ns);
    XMLNode act_job = req.NewChild("types:" + action + "Request").NewChild("types:JobDescriptionList");
    act_job.NewChild("types:JDL") = jdl_text;
    act_job.NewChild("types:autoStart") = "false";
    if (!delegationId.empty())
      act_job.NewChild("types:delegationId") = delegationId;

    XMLNode response;
    if (!process(req, response))
      return false;

    if (!response) {
      logger.msg(VERBOSE, "Empty response");
      return false;
    }

    if (!response["jobId"]["id"]) {
      logger.msg(VERBOSE, "No job ID in response");
      return false;
    }

    info.jobId = (std::string)response["jobId"]["id"];
    if (response["jobId"]["creamURL"])
      info.creamURL = URL((std::string)response["jobId"]["creamURL"]);
    for (XMLNode property = response["jobId"]["property"]; property; ++property) {
      if ((std::string)property["name"] == "CREAMInputSandboxURI")
        info.ISB_URI = (std::string)property["value"];
      else if ((std::string)property["name"] == "CREAMOutputSandboxURI")
        info.OSB_URI = (std::string)property["value"];
    }

    return true;
  }

Here is the call graph for this function:

void Arc::CREAMClient::setDelegationId ( const std::string &  delegId) [inline]

Definition at line 30 of file CREAMClient.h.

                                                   {
      this->delegationId = delegId;
    }

Here is the caller graph for this function:

bool Arc::CREAMClient::startJob ( const std::string &  jobid)

Definition at line 397 of file CREAMClient.cpp.

                                                   {
    logger.msg(VERBOSE, "Creating and sending job start request");

    action = "JobStart";

    PayloadSOAP req(cream_ns);
    XMLNode jobStartRequest = req.NewChild("types:" + action + "Request");
    jobStartRequest.NewChild("types:jobId").NewChild("types:id") = jobid;
    if (!delegationId.empty())
      jobStartRequest.NewChild("types:delegationId") = delegationId;

    XMLNode response;
    if (!process(req, response))
      return false;

    if (!response) {
      logger.msg(VERBOSE, "Empty response");
      return false;
    }

    if (!response["jobId"]["id"]) {
      logger.msg(VERBOSE, "No job ID in response");
      return false;
    }

    return true;
  }

Here is the call graph for this function:

bool Arc::CREAMClient::stat ( const std::string &  jobid,
Job job 
)

Definition at line 161 of file CREAMClient.cpp.

                                                         {
    logger.msg(VERBOSE, "Creating and sending a status request");

    action = "JobInfo";

    PayloadSOAP req(cream_ns);
    XMLNode jobStatusRequest = req.NewChild("types:" + action). // Should not be concatenated with "Request", as in the other requests.
                                   NewChild("types:jobId").
                                   NewChild("types:id") = jobid;
    if (!delegationId.empty())
      jobStatusRequest.NewChild("types:delegationProxyId") = delegationId;

    XMLNode response;
    if (!process(req, response))
      return false;

    XMLNode jobInfoNode;
    jobInfoNode = response["jobInfo"];

    XMLNode lastStatusNode = jobInfoNode.Path("status").back();

    if (lastStatusNode["name"])
      job.State = JobStateCREAM((std::string)lastStatusNode["name"]);

    if (!job.State) {
      logger.msg(VERBOSE, "Unable to retrieved job status.");
      return false;
    }

    if (ISVALID(jobInfoNode["jobId"]["id"]) && ISVALID(jobInfoNode["jobId"]["creamURL"]))
      job.JobID = URL((std::string)jobInfoNode["jobId"]["creamURL"] + "/" + (std::string)jobInfoNode["jobId"]["id"]);
    if (ISVALID(jobInfoNode["jobId"]["creamURL"])) {
      job.IDFromEndpoint = URL((std::string)jobInfoNode["jobId"]["creamURL"]);
      job.ExecutionCE = job.IDFromEndpoint.fullstr();
      job.JobManagementEndpoint = job.IDFromEndpoint.fullstr();
    }
    if (ISVALID(jobInfoNode["jobId"]["id"]))
      job.LocalIDFromManager = (std::string)jobInfoNode["jobId"]["id"];
    if (ISVALID(jobInfoNode["type"]))
      job.Type = (std::string)jobInfoNode["type"];
    if (ISVALID(jobInfoNode["JDL"])) {
      job.JobDescription = (std::string)jobInfoNode["JDL"];

      JobDescription jd;
      if (jd.Parse(job.JobDescription) && jd) {
        if (!jd.Application.Input.empty())
          job.StdIn = jd.Application.Input;

        if (!jd.Application.Output.empty())
          job.StdOut = jd.Application.Output;

        if (!jd.Application.Error.empty())
          job.StdErr = jd.Application.Error;

        if (!jd.Resources.CandidateTarget.empty())
          job.Queue = jd.Resources.CandidateTarget.front().QueueName;
      }
    }
    if (ISVALID(lastStatusNode["exitCode"]))
      job.ExitCode = stringtoi((std::string)lastStatusNode["exitCode"]);
    if (job.State() == "DONE-FAILED")
      job.Error.push_back((std::string)lastStatusNode["failureReason"]);
    if (ISVALID(jobInfoNode["delegationProxyInfo"])) {
      std::string delegationProxy = (std::string)jobInfoNode["delegationProxyInfo"];
      std::list<std::string> splited_proxy;
      tokenize(delegationProxy, splited_proxy, "\n");
      for (std::list<std::string>::iterator it = splited_proxy.begin();
           it != splited_proxy.end(); it++) {
        if (it->find("Holder Subject") < it->find(":"))
          job.Owner = it->substr(it->find_first_of(":") + 1);
        if (it->find("Valid To") < it->find(":")) {
          Time time;
          if (stringtoTime(it->substr(it->find_first_of(":") + 2), time) && time.GetTime() != -1)
            job.ProxyExpirationTime = time;
        }
      }
    }
    if (ISVALID(jobInfoNode["localUser"]))
      job.LocalOwner = (std::string)jobInfoNode["localUser"];
    if (ISVALID(jobInfoNode["lastCommand"])) {
      int job_register_id_first = -1;
      int job_register_id_last = -1;
      int job_start_id_first = -1;
      int job_start_id_last = -1;
      int local_id = 0;
      while (true) {
        if (!jobInfoNode["lastCommand"][local_id])
          break;
        if ((std::string)jobInfoNode["lastCommand"][local_id]["name"] == "JOB_REGISTER") {
          if (job_register_id_first == -1 && job_register_id_last == -1) {
            job_register_id_first = local_id;
            job_register_id_last = local_id;
          }
          else if (job_register_id_last > -1)
            job_register_id_last = local_id;
        }  //end of the JOB_REGISTER

        if ((std::string)jobInfoNode["lastCommand"][local_id]["name"] == "JOB_START") {
          if (job_start_id_first == -1 && job_start_id_last == -1) {
            job_start_id_first = local_id;
            job_start_id_last = local_id;
          }
          else if (job_start_id_last > -1)
            job_start_id_last = local_id;
        }  //end of the JOB_START
        local_id++;
      }

      //dependent on JOB_REGISTER
      if (job_register_id_first > -1)
        if (ISVALID(jobInfoNode["lastCommand"][job_register_id_first]["creationTime"])) {
          Time time((std::string)jobInfoNode["lastCommand"][job_register_id_first]["creationTime"]);
          if (time.GetTime() != -1)
            job.SubmissionTime = time;
        }

      if (job_register_id_last > -1)
        if (ISVALID(jobInfoNode["lastCommand"][job_register_id_last]["creationTime"])) {
          Time time((std::string)jobInfoNode["lastCommand"][job_register_id_last]["creationTime"]);
          if (time.GetTime() != -1)
            job.CreationTime = time;
        }
      //end of the JOB_REGISTER

      //dependent on JOB_START
      if (job_start_id_first > -1) {
        if (ISVALID(jobInfoNode["lastCommand"][job_start_id_first]["startSchedulingTime"])) {
          Time time((std::string)jobInfoNode["lastCommand"][job_start_id_first]["startSchedulingTime"]);
          if (time.GetTime() != -1)
            job.ComputingManagerSubmissionTime = time;
        }

        if (ISVALID(jobInfoNode["lastCommand"][job_start_id_first]["startProcessingTime"])) {
          Time time((std::string)jobInfoNode["lastCommand"][job_start_id_first]["startProcessingTime"]);
          if (time.GetTime() != -1)
            job.StartTime = time;
        }
      }

      if (job_start_id_last > -1)
        if (ISVALID(jobInfoNode["lastCommand"][job_start_id_last]["executionCompletedTime"])) {
          Time time((std::string)jobInfoNode["lastCommand"][job_start_id_last]["executionCompletedTime"]);
          if (time.GetTime() != -1)
            job.ComputingManagerEndTime = time;
        }
      //end of the JOB_START
    } //end of the LastCommand
    if (ISVALID(lastStatusNode["timestamp"]) && (job.State() == "DONE-OK" || job.State() == "DONE-FAILED")) {
      Time time((std::string)lastStatusNode["timestamp"]);
      if (time.GetTime() != -1)
        job.EndTime = time;
    }

    return true;
  }

Here is the call graph for this function:


Member Data Documentation

std::string Arc::CREAMClient::action [private]

Definition at line 45 of file CREAMClient.h.

std::string Arc::CREAMClient::cadir [private]

Definition at line 49 of file CREAMClient.h.

std::string Arc::CREAMClient::cafile [private]

Definition at line 48 of file CREAMClient.h.

Definition at line 47 of file CREAMClient.h.

Definition at line 50 of file CREAMClient.h.

std::string Arc::CREAMClient::delegationId [private]

Definition at line 51 of file CREAMClient.h.

Logger Arc::CREAMClient::logger [static, private]

Definition at line 52 of file CREAMClient.h.


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