Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes
Paul::PaulService Class Reference

#include <paul.h>

Inheritance diagram for Paul::PaulService:
Inheritance graph
[legend]
Collaboration diagram for Paul::PaulService:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 PaulService (Arc::Config *cfg)
virtual ~PaulService (void)
Arc::MCC_Status process (Arc::Message &in, Arc::Message &out)
 Method for processing of requests and responses.
bool RegistrationCollector (Arc::XMLNode &doc)
 Service specific registartion collector, used for generate service registartions.
void GetActivities (const std::string &url, std::vector< std::string > &ret)
virtual void AddSecHandler (Config *cfg, ArcSec::SecHandler *sechandler, const std::string &label="")
 Add security components/handlers to this MCC.
virtual std::string getID ()
 Service may implement own service identitifer gathering method.

Protected Member Functions

bool information_collector (Arc::XMLNode &doc)
void do_request (void)
void do_report (void)
void do_action (void)
bool stage_in (Job &j)
bool run (Job &j)
bool stage_out (Job &j)
bool ProcessSecHandlers (Message &message, const std::string &label="") const
 Executes security handlers of specified queue.

Static Protected Member Functions

static void process_job (void *arg)
static void request_loop (void *arg)
static void report_and_action_loop (void *arg)

Protected Attributes

Configurator configurator
std::string uuid
std::string endpoint
bool in_shutdown
Arc::NS ns_
Arc::Logger logger_
JobQueue jobq
std::map< std::string, Arc::Run * > runq
SysInfo sysinfo
std::map< std::string,
std::list< ArcSec::SecHandler * > > 
sechandlers_
 Set of labeled authentication and authorization handlers.

Static Protected Attributes

static Logger logger
 Logger object used to print messages generated by this class.

Detailed Description

Definition at line 18 of file paul.h.


Constructor & Destructor Documentation

Definition at line 459 of file paul.cpp.

                                      :RegisteredService(cfg),in_shutdown(false),logger_(Arc::Logger::rootLogger, "Paul"),configurator(cfg)
{
    // Define supported namespaces
    ns_["ibes"] = "http://www.nordugrid.org/schemas/ibes";
    ns_["glue2"] = "http://schemas.ogf.org/glue/2008/05/spec_2.0_d42_r1";
    ns_["sched"] = "http://www.nordugrid.org/schemas/sched";
    ns_["wsa"] = "http://www.w3.org/2005/08/addressing";

    configurator.setJobQueue(&jobq);
    // Start sched thread
    Arc::CreateThreadFunction(&request_loop, this);
    // Start report and action thread
    Arc::CreateThreadFunction(&report_and_action_loop, this);
}

Here is the call graph for this function:

Paul::PaulService::~PaulService ( void  ) [virtual]

Definition at line 475 of file paul.cpp.

{
    in_shutdown = true;
    logger_.msg(Arc::VERBOSE, "PaulService shutdown");
    std::map<std::string, Arc::Run *>::iterator it;
    for (it = runq.begin(); it != runq.end(); it++) {
        if (it->second != NULL) {
            logger_.msg(Arc::VERBOSE, "Terminate job %s", it->first);
            Arc::Run *r = it->second;
            r->Kill(1);
        }
    }
}

Here is the call graph for this function:


Member Function Documentation

void Arc::Service::AddSecHandler ( Config cfg,
ArcSec::SecHandler sechandler,
const std::string &  label = "" 
) [virtual, inherited]

Add security components/handlers to this MCC.

For more information please see description of MCC::AddSecHandler

Definition at line 14 of file Service.cpp.

                                                                                           {
    if(sechandler) {
        sechandlers_[label].push_back(sechandler); //need polishing to put the SecHandlerFactory->getinstance here
        XMLNode cn = (*cfg)["SecHandler"];
        Config cfg_(cn);
    }
}

Here is the caller graph for this function:

void Paul::PaulService::do_action ( void  ) [protected]

Definition at line 321 of file paul.cpp.

{
    logger_.msg(Arc::VERBOSE, "Get activity status changes");   
    std::map<const std::string, Job *> all = jobq.getAllJobs();
    std::map<const std::string, Job *>::iterator it;
    std::map<std::string, Arc::PayloadSOAP *> requests;
    // collect schedulers 
    for (it = all.begin(); it != all.end(); it++) {
        Job *j = it->second;
        std::string sched_url = j->getResourceID();
        Arc::XMLNode get;
        std::map<std::string, Arc::PayloadSOAP *>::iterator r = requests.find(sched_url);
        if (r == requests.end()) {
            Arc::PayloadSOAP *request = new Arc::PayloadSOAP(ns_);
            get = request->NewChild("ibes:GetActivitiesStatusChanges");
            requests[sched_url] = request;
        } else {
            get = (*r->second)["ibes:GetActivitiesStatusChanges"];
        }
        // Make response
        Arc::WSAEndpointReference identifier(get.NewChild("ibes:ActivityIdentifier"));
        identifier.Address(j->getResourceID()); // address of scheduler service
        identifier.ReferenceParameters().NewChild("sched:JobID") = j->getID();
    }
    
    Arc::MCCConfig cfg;
    // call get activitiy changes to all scheduler
    std::map<std::string, Arc::PayloadSOAP *>::iterator i;
    for (i = requests.begin(); i != requests.end(); i++) {
        std::string sched_url = i->first;
        Arc::PayloadSOAP *request = i->second;
        Arc::ClientSOAP *client;
        Arc::URL url(sched_url);
        if (url.Protocol() == "https") {
            cfg.AddPrivateKey(configurator.getPki()["PrivateKey"]);
            cfg.AddCertificate(configurator.getPki()["CertificatePath"]);
            cfg.AddCAFile(configurator.getPki()["CACertificatePath"]);
            cfg.AddCADir(configurator.getPki()["CACertificatesDir"]);
        }
        client = new Arc::ClientSOAP(cfg, url, 60);
        Arc::PayloadSOAP *response;
        Arc::MCC_Status status = client->process(request, &response);
        if (!status) {
            logger_.msg(Arc::ERROR, "Request failed");
            if (response) {
                std::string str;
                response->GetXML(str);
                logger_.msg(Arc::ERROR, str);
                delete response;
            }
            delete client;
            continue;
        }
        if (!response) {
            logger_.msg(Arc::ERROR, "No response");
            delete response;
            delete client;
            continue;
        }
    
        // Handle soap level error
        Arc::XMLNode fs;
        (*response)["Fault"]["faultstring"].New(fs);
        std::string faultstring = (std::string)fs;
        if (faultstring != "") {
            logger_.msg(Arc::ERROR, faultstring);
            delete response;
            delete client;
            continue;
        }
        delete client;
        // process response
        Arc::XMLNode activities = (*response)["ibes:GetActivitiesStatusChangesResponse"]["Activities"];
        Arc::XMLNode activity;
        for (int i = 0; (activity = activities["Activity"][i]) != false; i++) {
            Arc::XMLNode id = activity["ActivityIdentifier"];
            Arc::WSAEndpointReference epr(id);
            std::string job_id = epr.ReferenceParameters()["sched:JobID"];
            if (job_id.empty()) {
                logger_.msg(Arc::WARNING, "Cannot find job id");
            }
            std::string new_status = (std::string)activity["NewState"];
            Job &j = jobq[job_id];
            if (j.isFinishedReported()) {
                // skip job which was already finished
                continue;
            }
            logger.msg(Arc::VERBOSE, "%s new status: %s", j.getID(), new_status);
            j.setStatus(sched_status_from_string(new_status));
            // do actions
            if (j.getStatus() == KILLED) { 
                j.setStatus(FINISHED);
            }
            if (j.getStatus() == KILLING) {
                Arc::Run *run = runq[job_id];
                if (run != NULL) {
                    logger_.msg(Arc::VERBOSE, "Killing %s", job_id);
                    run->Kill(1);
                }
                j.setStatus(KILLED);
            }
        }
        delete response;
    }
    // free
    for (i = requests.begin(); i != requests.end(); i++) {
        delete i->second;
    }
    // cleanup finished process
    for (it = all.begin(); it != all.end(); it++) {
        Job *j = it->second;
        logger_.msg(Arc::VERBOSE, "pre cleanup %s %d", j->getID(), j->getStatus());
        if (j->getStatus() == FINISHED || j->getStatus() == FAILED) {
            // do clean if and only if the finished state already reported
            if (j->isFinishedReported()) {
                logger_.msg(Arc::VERBOSE, "cleanup %s", j->getID());
                j->clean(configurator.getJobRoot());
                logger_.msg(Arc::VERBOSE, "cleanup 2 %s", j->getID());
                jobq.removeJob(*j);
            }           
        } 
    }

}

Here is the call graph for this function:

void Paul::PaulService::do_report ( void  ) [protected]

Definition at line 213 of file paul.cpp.

{
    logger_.msg(Arc::VERBOSE, "Report status");
    std::map<const std::string, Job *> all = jobq.getAllJobs();
    std::map<const std::string, Job *>::iterator it;
    std::map<std::string, Arc::PayloadSOAP *> requests;

    for (it = all.begin(); it != all.end(); it++) {
        Job *j = it->second;
        std::string sched_url = j->getResourceID();
        Arc::XMLNode report;
        std::map<std::string, Arc::PayloadSOAP *>::iterator r = requests.find(sched_url);
        if (r == requests.end()) {
            Arc::PayloadSOAP *request = new Arc::PayloadSOAP(ns_);
            report = request->NewChild("ibes:ReportActivitiesStatus");
            requests[sched_url] = request;
        } else {
            report = (*r->second)["ibes:ReportActivitiesStatus"];
        }
        
        Arc::XMLNode activity = report.NewChild("ibes:Activity");
        
        // request
        Arc::WSAEndpointReference identifier(activity.NewChild("ibes:ActivityIdentifier"));
        identifier.Address(j->getResourceID()); // address of scheduler service
        identifier.ReferenceParameters().NewChild("sched:JobID") = j->getID();

        Arc::XMLNode state = activity.NewChild("ibes:ActivityStatus");
        std::string s = sched_status_to_string(j->getStatus());
        logger.msg(Arc::VERBOSE, "%s reported %s", j->getID(), s);
        state.NewAttribute("ibes:state") = s;
        
    }
    
    Arc::MCCConfig cfg;
    Arc::ClientSOAP *client;

    std::map<std::string, Arc::PayloadSOAP *>::iterator i;
    for (i = requests.begin(); i != requests.end(); i++) {
        std::string url_str = i->first;
        Arc::PayloadSOAP *request = i->second;
        Arc::URL url(url_str);
        if (url.Protocol() == "https") {
            cfg.AddPrivateKey(configurator.getPki()["PrivateKey"]);
            cfg.AddCertificate(configurator.getPki()["CertificatePath"]);
            cfg.AddCAFile(configurator.getPki()["CACertificatePath"]);
            cfg.AddCADir(configurator.getPki()["CACertificatesDir"]);
        }
        client = new Arc::ClientSOAP(cfg, url, 60);

        Arc::PayloadSOAP *response;
        Arc::MCC_Status status = client->process(request, &response);
        if (!status) {
            logger_.msg(Arc::ERROR, "Request failed");
            if (response) {
                std::string str;
                response->GetXML(str);
                logger_.msg(Arc::ERROR, str);
                delete response;
            }
            delete client;
            continue;
        }
        if (!response) {
            logger_.msg(Arc::ERROR, "No response");
            delete response;
            delete client;
            continue;
        }
    
        // Handle soap level error
        Arc::XMLNode fs;
        (*response)["Fault"]["faultstring"].New(fs);
        std::string faultstring = (std::string)fs;
        if (faultstring != "") {
            logger_.msg(Arc::ERROR, faultstring);
            delete response;
            delete client;
            continue;
        }
        delete response;
        delete client;
        // delete client;
        // mark all finsihed job as sucessfully reported finished job
        Arc::XMLNode req = (*request)["ibes:ReportActivitiesStatus"];
        Arc::XMLNode activity;
        for (int i = 0; (activity = req["Activity"][i]) != false; i++) {
            Arc::XMLNode id = activity["ActivityIdentifier"];
            Arc::WSAEndpointReference epr(id);
            std::string job_id = epr.ReferenceParameters()["sched:JobID"];
            if (job_id.empty()) {
                logger_.msg(Arc::ERROR, "Cannot find job id");
                continue;
            }
            logger_.msg(Arc::VERBOSE, "%s reported", job_id);
            Job &j = jobq[job_id];
            if (j.getStatus() == FINISHED || j.getStatus() == FAILED) {
                logger_.msg(Arc::VERBOSE, "%s job reported finished", j.getID());
                j.finishedReported();
            }
        }
    }
    // free
    for (i = requests.begin(); i != requests.end(); i++) {
        delete i->second;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Paul::PaulService::do_request ( void  ) [protected]

Definition at line 162 of file paul.cpp.

{
    // XXX pickup scheduler randomly from schdeuler list
    std::vector<std::string> schedulers = configurator.getSchedulers();
    if (schedulers.size() == 0) {
        logger_.msg(Arc::WARNING, "No scheduler configured");
        return;
    }
    std::string url = schedulers[0];
    // XXX check if there is no scheduler
    logger_.msg(Arc::VERBOSE, "Do Request: %s", url);
    // check if there is no free CPU slot
    int active_job = 0;
    std::map<const std::string, Job *> all = jobq.getAllJobs();
    std::map<const std::string, Job *>::iterator it;
    for (it = all.begin(); it != all.end(); it++) {
        Job *j = it->second;
        SchedStatusLevel status = j->getStatus();
        if (status == NEW || status == STARTING || status == RUNNING) {
            active_job++;
        }
    }
    int cpu_num = sysinfo.getPhysicalCPUs();
    if (active_job >= cpu_num) {
        logger_.msg(Arc::VERBOSE, "No free CPU slot");
        return;
    }
    std::vector<std::string> job_ids;
    GetActivities(url, job_ids);
    for (int i = 0; i < job_ids.size(); i++) {
        ServiceAndJob *arg = new ServiceAndJob;
        arg->self = this;
        arg->job_id = new std::string(job_ids[i]);
        Arc::CreateThreadFunction(&process_job, arg);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Paul::PaulService::GetActivities ( const std::string &  url,
std::vector< std::string > &  ret 
)

Definition at line 39 of file paul.cpp.

{
    // Collect information about resources
    // and create Glue compatibile Resource description
    Arc::NS glue2_ns;
    glue2_ns["glue2"] = ns_["glue2"];
    Arc::XMLNode glue2(glue2_ns, "Domains");
    if (information_collector(glue2) == false) {
        logger_.msg(Arc::ERROR, "Cannot collect resource information");
        return;
    }
    {
        std::string str;
        glue2.GetDoc(str);
        logger_.msg(Arc::VERBOSE, str);
    }
    // Create client to url
    Arc::ClientSOAP *client;
    Arc::MCCConfig cfg;
    Arc::URL url(url_str);
    if (url.Protocol() == "https") {
        cfg.AddPrivateKey(configurator.getPki()["PrivateKey"]);
        cfg.AddCertificate(configurator.getPki()["CertificatePath"]);
        cfg.AddCAFile(configurator.getPki()["CACertificatePath"]);
        cfg.AddCADir(configurator.getPki()["CACertificatesDir"]);
    }
    client = new Arc::ClientSOAP(cfg, url, 60);
    // invoke GetActivity SOAP call
    Arc::PayloadSOAP request(ns_);
    request.NewChild("ibes:GetActivities").NewChild(glue2);
    Arc::PayloadSOAP *response;
    Arc::MCC_Status status = client->process(&request, &response);
    if (!status) {
        logger_.msg(Arc::ERROR, "Request failed");
        if (response) {
           std::string str;
           response->GetXML(str);
           logger_.msg(Arc::ERROR, str);
           delete response;
        }
        delete client;
        return;
    }
    if (!response) {
        logger_.msg(Arc::ERROR, "No response");
        delete client;
        return;
    }
    
    // Handle soap level error
    Arc::XMLNode fs;
    (*response)["Fault"]["faultstring"].New(fs);
    std::string faultstring = (std::string)fs;
    if (faultstring != "") {
        logger_.msg(Arc::ERROR, faultstring);
        delete response;
        delete client;
        return;
    }
    delete client;
    // Create jobs from response
    Arc::XMLNode activities;
    activities = (*response)["ibes:GetActivitiesResponse"]["ibes:Activities"];
    Arc::XMLNode activity;
    for (int i = 0; (activity = activities.Child(i)) != false; i++) {
        Arc::XMLNode id = activity["ActivityIdentifier"];
        if (!id) {
            logger_.msg(Arc::VERBOSE, "Missing job identifier");
            continue;
        }
        Arc::WSAEndpointReference epr(id);
        std::string job_id = epr.ReferenceParameters()["sched:JobID"];
        if (job_id.empty()) {
            logger_.msg(Arc::VERBOSE, "Cannot find job id");
            continue;
        }
        std::string resource_id = epr.Address();
        if (resource_id.empty()) {
            logger_.msg(Arc::VERBOSE, "Cannot find scheduler endpoint");
            continue;
        }
        Arc::XMLNode jsdl = activity["ActivityDocument"]["JobDefinition"];
        JobRequest jr(jsdl);
        Job j(jr);
        j.setStatus(NEW);
        j.setID(job_id);
        j.setResourceID(resource_id); // here the resource is the scheduler endpoint
        ret.push_back(job_id);
        jobq.addJob(j);
        std::string s = sched_status_to_string(j.getStatus());
        logger_.msg(Arc::VERBOSE, "Status: %s %d",s,j.getStatus());
        // j.save();
    }
    delete response;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual std::string Arc::Service::getID ( ) [inline, virtual, inherited]

Service may implement own service identitifer gathering method.

This method return identifier of service which is used for registering it Information Services.

Reimplemented in ARex::ARexService.

Definition at line 69 of file Service.h.

{ return ""; };

Definition at line 13 of file info.cpp.

{
    // refresh dynamic system information
    sysinfo.refresh();
    // common variables
    std::string created = TimeStamp(Arc::UTCTime);
    std::string validity = Arc::tostring(configurator.getPeriod()*2);
    std::string id = "urn:nordugrid:paul:" + Arc::UUID(); 
    std::string ee_id = id + ":executionenvironment:0";
    // Set Domain
    doc.NewAttribute("CreationTime") = created;
    doc.NewAttribute("Validity") = validity;
    // Set AdminDomain
    Arc::XMLNode ad = doc.NewChild("AdminDomain");
    ad.NewAttribute("CreationTime") = created;
    ad.NewAttribute("Validity") = validity;
    ad.NewAttribute("BaseType") = "Domain";
    ad.NewChild("ID") = id;
    ad.NewChild("Distributed") = "False";
    // Set Computing Service
    //      Service Part
    Arc::XMLNode services = ad.NewChild("Services");
    Arc::XMLNode cs = services.NewChild("ComputingService");
    cs.NewAttribute("CreationTime") = created;
    cs.NewAttribute("Validity") = validity;
    cs.NewAttribute("BaseType") = "Service";
    cs.NewChild("ID") = id + ":computingservice:0";
    cs.NewChild("Name") = "Arc Paul Service";
    cs.NewChild("Type") = "org.nordugrid.paul";
    cs.NewChild("QualityLevel") = "production";
    // No endpont -> pull modell
    //      Computing Service part
    cs.NewChild("TotalJobs") = Arc::tostring(jobq.getTotalJobs());
    cs.NewChild("RunningJobs") = Arc::tostring(jobq.getRunningJobs());
    cs.NewChild("WaitingJobs") = Arc::tostring(jobq.getWaitingJobs());
    cs.NewChild("StagingJobs") = Arc::tostring(jobq.getStagingJobs());
    Arc::XMLNode sh = cs.NewChild("ComputingShares").NewChild("ComputingShare");
    sh.NewAttribute("CreationTime") = created;
    sh.NewAttribute("Validity") = validity;
    sh.NewAttribute("BaseType") = "Share";
    //      Share part
    sh.NewChild("LocalID") = "computingshare:0";
    //      Computing Share part
    sh.NewChild("MaxTotalJobs") = Arc::tostring(sysinfo.getLogicalCPUs());
    sh.NewChild("MaxMemory") = Arc::tostring((int)sysinfo.getMainMemorySize()); // in MB
    sh.NewChild("MaxDiskSpace") = Arc::tostring((int)(SysInfo::diskFree(configurator.getJobRoot())/1024)); // in GB
    sh.NewChild("ServingState") = "production";
    sh.NewChild("TotalJobs") = Arc::tostring(jobq.getTotalJobs());
    sh.NewChild("RunningJobs") = Arc::tostring(jobq.getRunningJobs());
    sh.NewChild("WaitingJobs") = Arc::tostring(jobq.getWaitingJobs());
    sh.NewChild("StagingJobs") = Arc::tostring(jobq.getStagingJobs());
    sh.NewChild("Associations").NewChild("ExecutionEnvironmentLocalID") = ee_id;
    //      Manager part
    Arc::XMLNode mg = cs.NewChild("ComputingManager");
    mg.NewAttribute("CreationTime") = created;
    mg.NewAttribute("Validity") = validity;
    mg.NewAttribute("BaseType") = "Manager";
    mg.NewChild("ID") = id + ":computingmanager:0";
    mg.NewChild("Name") = "Paul";
    //      Computing Manager part
    mg.NewChild("Type") = "fork";
    mg.NewChild("Version") = "1.0";
    mg.NewChild("TotalPhysicalCPUs") = Arc::tostring(sysinfo.getPhysicalCPUs());
    mg.NewChild("TotalLogicalCPUs") = Arc::tostring(sysinfo.getLogicalCPUs());
    mg.NewChild("Homogenety") = "True";
    mg.NewChild("WorkingAreaTotal") = Arc::tostring((int)(SysInfo::diskTotal(configurator.getJobRoot())/1024)); // in GB
    mg.NewChild("WorkingAreaFree") = Arc::tostring((int)(SysInfo::diskFree(configurator.getJobRoot())/1024)); // in GB
    // Application environment
    Arc::XMLNode appenvs = configurator.getApplicationEnvironments();
    Arc::XMLNode env;
    if (appenvs) {
        Arc::XMLNode ae = mg.NewChild("ApplicationEnvironments");
        for (int i = 0; (env = appenvs["ApplicationEnvironment"][i]) != false; i++) {
            Arc::XMLNode cr_time = env.Attribute("CreationTime");
            if (!cr_time) { 
                cr_time = env.NewAttribute("CreationTime");
            }
            cr_time = created;
            Arc::XMLNode v_time = env.Attribute("Validity");
            if (!v_time) {
                v_time = env.NewAttribute("Validity");
            }
            v_time = validity;
            Arc::XMLNode local_id = env["LocalID"];
            if (!local_id) {
                env.NewChild("LocalID") = ("applicationenvironment:" + Arc::tostring(i));
            }
            Arc::XMLNode eid = env["Associations"]["ExecutionEnvironmentLocalID"];
            if (!eid) {
                env.NewChild("Associations").NewChild("ExecutionEnvironmentLocalID") = ee_id;
            }
            ae.NewChild(env);
        }
    }
    //  Resource part
    Arc::XMLNode exec = mg.NewChild("ExecutionEnvironment");
    exec.NewAttribute("CreationTime") = created;
    exec.NewAttribute("Validity") = validity;
    exec.NewAttribute("BaseType") = "Resource";
    exec.NewChild("ID") = ee_id;
    //  ExecutionEnvironment part
    exec.NewChild("Platform") = sysinfo.getPlatform();
    exec.NewChild("PhysicalCPUs") = Arc::tostring(sysinfo.getPhysicalCPUs());
    exec.NewChild("LogicalCPUs") = Arc::tostring(sysinfo.getLogicalCPUs());
    exec.NewChild("MainMemorySize") = Arc::tostring(sysinfo.getMainMemorySize()); // in MB
    exec.NewChild("VirtualMemorySize") = Arc::tostring(sysinfo.getVirtualMemorySize()); // in MB
    exec.NewChild("OSFamily") = sysinfo.getOSFamily();
    exec.NewChild("OSName") = sysinfo.getOSName();
    exec.NewChild("OSVersion") = sysinfo.getOSVersion();
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Arc::MCC_Status Paul::PaulService::process ( Arc::Message request,
Arc::Message response 
) [virtual]

Method for processing of requests and responses.

This method is called by preceeding MCC in chain when a request needs to be processed. This method must call similar method of next MCC in chain unless any failure happens. Result returned by call to next MCC should be processed and passed back to previous MCC. In case of failure this method is expected to generate valid error response and return it back to previous MCC without calling the next one.

Parameters:
requestThe request that needs to be processed.
responseA Message object that will contain the response of the request when the method returns.
Returns:
An object representing the status of the call.

Implements Arc::MCCInterface.

Definition at line 489 of file paul.cpp.

{
    return configurator.process(in, out);
}

Here is the call graph for this function:

void Paul::PaulService::process_job ( void *  arg) [static, protected]

Definition at line 140 of file paul.cpp.

{
    ServiceAndJob &info = *((ServiceAndJob *)arg);
    PaulService &self = *(info.self);
    Job &j = self.jobq[*(info.job_id)];
    self.logger_.msg(Arc::VERBOSE, "Process job: %s", j.getID());
    j.setStatus(STARTING);
    self.stage_in(j);
    self.run(j);
    if (!self.in_shutdown) {
        self.stage_out(j);
        if (j.getStatus() != KILLED && j.getStatus() != KILLING && j.getStatus() != FAILED) {
            self.logger_.msg(Arc::VERBOSE, "%s set finished", j.getID());
            j.setStatus(FINISHED);
        }
    }
    // free memory
    delete info.job_id;
    delete &info;
    self.logger_.msg(Arc::VERBOSE, "Finished job %s", j.getID());
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::Service::ProcessSecHandlers ( Message message,
const std::string &  label = "" 
) const [protected, inherited]

Executes security handlers of specified queue.

For more information please see description of MCC::ProcessSecHandlers

Definition at line 22 of file Service.cpp.

                                                                              {
    std::map<std::string,std::list<ArcSec::SecHandler*> >::const_iterator q = sechandlers_.find(label);
    if(q == sechandlers_.end()) {
        logger.msg(DEBUG, "No security processing/check requested for '%s'", label);
        return true;
    }

    std::list<ArcSec::SecHandler*>::const_iterator h = q->second.begin();
    for(;h!=q->second.end();++h) {
        const ArcSec::SecHandler* handler = *h;
        if(handler) if(!(handler->Handle(&message))) {
            logger.msg(DEBUG, "Security processing/check for '%s' failed", label);
            return false;
        }
    }
    logger.msg(DEBUG, "Security processing/check for '%s' passed", label);
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Service specific registartion collector, used for generate service registartions.

In implemented service this method should generate GLUE2 document with part of service description which service wishes to advertise to Information Services.

Reimplemented from Arc::Service.

Definition at line 125 of file info.cpp.

                                                       {
  logger_.msg(Arc::DEBUG,"Passing service's information from collector to registrator");
  Arc::XMLNode empty(ns_, "RegEntry");
  empty.New(doc);

  doc.NewChild("SrcAdv");
  doc.NewChild("MetaSrcAdv");
  doc["SrcAdv"].NewChild("Type") = "org.nordugrid.execution.paul";
  doc["SrcAdv"].NewChild("EPR").NewChild("Address") = configurator.getEndpoint();

  return true;
}

Here is the call graph for this function:

void Paul::PaulService::report_and_action_loop ( void *  arg) [static, protected]

Definition at line 447 of file paul.cpp.

{
    PaulService *self = (PaulService *)arg;
    for (;;) {
        self->do_report();
        self->do_action();
        int p = (int)(self->configurator.getPeriod()*1.1);
        sleep(p);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Paul::PaulService::request_loop ( void *  arg) [static, protected]

Definition at line 200 of file paul.cpp.

{
    PaulService *self = (PaulService *)arg;
    
    for (;;) {
        self->do_request();
        int p = self->configurator.getPeriod();
        self->logger_.msg(Arc::VERBOSE, "Per: %d", p);
        sleep(p);       
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Paul::PaulService::run ( Job j) [protected]

Definition at line 35 of file run.cpp.

{
    logger_.msg(Arc::VERBOSE, "Start process");
    Arc::XMLNode jd = j.getJSDL()["JobDescription"];
    Arc::XMLNode app = jd["Application"]["POSIXApplication"];
    if (app == false) {
        app = jd["Application"]["HPCProfileApplication"];
    }
    if (app == false) {
        logger_.msg(Arc::ERROR, "Invalid JSDL! Missing application section");
        if (j.getStatus() != KILLED || j.getStatus() != KILLING) {
            logger_.msg(Arc::VERBOSE, "%s set exception", j.getID());
            j.setStatus(FAILED);
        }
        return false;
    }
    std::string exec = (std::string)app["Executable"];
    // XXX protection against ../../ stuff in the executable and all kind
    // of path
    if (exec.empty()) {
        logger_.msg(Arc::ERROR, "Empty executable");
        if (j.getStatus() != KILLED || j.getStatus() != KILLING) {
            logger_.msg(Arc::VERBOSE, "%s set exception", j.getID());
            j.setStatus(FAILED);
        }
        return false;    
    }
    Arc::XMLNode arg;
    std::string arg_str = " ";
    for (int i=0; (arg = app["Argument"][i]) != false; i++) {
        arg_str += (std::string)arg + " ";
    }

    std::string std_in = (std::string)app["Input"];
    std::string std_out = (std::string)app["Output"];
    std::string std_err = (std::string)app["Error"];
    std::string cmd;

    std::string wd = Glib::build_filename(configurator.getJobRoot(), j.getID());
    mkdir(wd.c_str(), 0700);
    if (!Glib::path_is_absolute(exec)) {
#ifdef WIN32
        size_t found = exec.find_last_of(".");
        std::string extension = exec.substr(found+1);
        extension = Arc::upper(extension);
        if (extension == "BAT") {
          std::string cmd_path = Glib::find_program_in_path("cmd");
          logger_.msg(Arc::VERBOSE, "Windows cmd path: %s", cmd_path);
          cmd = cmd_path + " /c " + exec;
        }
        if (extension != "BAT")
#endif
        cmd = Glib::build_filename(wd, exec);
        chmod(cmd.c_str(), 0700);
#ifndef WIN32
        cmd = "./" + exec + arg_str;
#else
        cmd += (" " + arg_str);
#endif
    } else {
        cmd = exec + arg_str;
    }
#ifdef WIN32
    cmd = save_filename(cmd);
#endif
    logger_.msg(Arc::VERBOSE, "Cmd: %s", cmd);

    Arc::Run *run = NULL;
    try {
        run = new Arc::Run(cmd);
        if (!std_in.empty())
          run->AssignStdin(std_in);
        if (!std_out.empty())
          run->AssignStdout(std_out);
        if (!std_err.empty())
          run->AssignStderr(std_err);
        run->AssignWorkingDirectory(wd);
        logger_.msg(Arc::VERBOSE, "Command: %s", cmd);
        if(!run->Start()) {
            logger_.msg(Arc::ERROR, "Cannot start application");
            goto error;
        }
        j.setStatus(RUNNING);
        runq[j.getID()] = run;
        if(run->Wait()) {
            logger_.msg(Arc::VERBOSE, "StdOut: %s", std_out);
            logger_.msg(Arc::VERBOSE, "StdErr: %s", std_err);
            if (run != NULL) {
                //logger_.msg(Arc::VERBOSE, "delete run");

                // TODO: erase should be delayed
                //runq.erase(j.getID());

                delete run;
                run = NULL;
            }
            logger_.msg(Arc::VERBOSE, "return from run");
            if (j.getStatus() != KILLED && j.getStatus() != KILLING) {
                logger_.msg(Arc::VERBOSE, "%s set finished", j.getID());
                j.setStatus(FINISHED);
            }
            return true;
        } else {
            logger_.msg(Arc::ERROR, "Error during the application run");
            goto error;
        }
        /* int r = */ run->Result();
    } catch (std::exception &e) {
        logger_.msg(Arc::ERROR, "Exception: %s", e.what());
        goto error;
    } catch (Glib::SpawnError &e) {
        logger_.msg(Arc::ERROR, "SpawnError");
        goto error;
    } catch (Glib::SpawnError &e) {
        std::cerr << e.what() << std::endl;
    }

error:
    if (j.getStatus() != KILLED && j.getStatus() != KILLING) {
        logger_.msg(Arc::VERBOSE, "%s set exception", j.getID());
        j.setStatus(FAILED);
    }
    if (run != NULL) {
        runq.erase(j.getID());
        delete run;
        run = NULL;
    }
    return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Paul::PaulService::stage_in ( Job j) [protected]

Definition at line 211 of file stage.cpp.

{
    logger_.msg(Arc::VERBOSE, "Stage in");
    
    FileTransfer ft(configurator.getCachePath());
    ft.download(configurator.getJobRoot(), j);
    return true;
}

Here is the call graph for this function:

bool Paul::PaulService::stage_out ( Job j) [protected]

Definition at line 220 of file stage.cpp.

{
    logger_.msg(Arc::VERBOSE, "Stage out");
    FileTransfer ft(configurator.getCachePath());
    ft.upload(configurator.getJobRoot(), j);
    return true;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 20 of file paul.h.

std::string Paul::PaulService::endpoint [protected]

Definition at line 22 of file paul.h.

Definition at line 23 of file paul.h.

Definition at line 26 of file paul.h.

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

Logger object used to print messages generated by this class.

Reimplemented in Echo::Service_Echo, Arc::Service_JavaWrapper, SPService::Service_SP, Compiler::Service_Compiler, Hopi::Hopi, and Arc::Service_PythonWrapper.

Definition at line 43 of file Service.h.

Definition at line 25 of file paul.h.

Definition at line 24 of file paul.h.

std::map<std::string, Arc::Run *> Paul::PaulService::runq [protected]

Definition at line 28 of file paul.h.

std::map<std::string,std::list<ArcSec::SecHandler*> > Arc::Service::sechandlers_ [protected, inherited]

Set of labeled authentication and authorization handlers.

MCC calls sequence of handlers at specific point depending on associated identifier. in most aces those are "in" and "out" for incoming and outgoing messages correspondingly.

Definition at line 40 of file Service.h.

Definition at line 29 of file paul.h.

std::string Paul::PaulService::uuid [protected]

Definition at line 21 of file paul.h.


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