Arc::MCC_Status ARexService::ESWipeActivity(ARexGMConfig& config,Arc::XMLNode in,Arc::XMLNode out) { /* esmanag:WipeActivity estypes:ActivityID esmanag:WipeActivityResponse esmanag:WipeActivityResponseItem estypes:ActivityID . esmanag:EstimatedTime (xsd:unsignedLong) estypes:InternalBaseFault OperationNotPossibleFault OperationNotAllowedFault ActivityNotFoundFault AccessControlFault estypes:VectorLimitExceededFault estypes:AccessControlFault estypes:InternalBaseFault */ Arc::XMLNode id = in["ActivityID"]; unsigned int n = 0; for(;(bool)id;++id) { if((++n) > MAX_ACTIVITIES) { Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,""); ESVectorLimitExceededFault(fault,MAX_ACTIVITIES,"Too many ActivityID"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; }; id = in["ActivityID"]; for(;(bool)id;++id) { std::string jobid = id; Arc::XMLNode item = out.NewChild("esmanag:WipeActivityResponseItem"); item.NewChild("estypes:ActivityID") = jobid; ARexJob job(jobid,config,logger_); if(!job) { // There is no such job logger_.msg(Arc::ERROR, "EMIES:WipeActivity: job %s - %s", jobid, job.Failure()); ESActivityNotFoundFault(item.NewChild("dummy"),job.Failure()); } else { if((job.State() != "FINISHED") && (job.State() != "DELETED")) { logger_.msg(Arc::ERROR, "EMIES:WipeActivity: job %s - state is %s, not terminal", jobid, job.State()); ESOperationNotAllowedFault(item.NewChild("dummy"),"Not in terminal state"); } else if(!job.Clean()) { // Probably wrong current state logger_.msg(Arc::ERROR, "EMIES:WipeActivity: job %s - %s", jobid, job.Failure()); // TODO: check for real reason ESOperationNotAllowedFault(item.NewChild("dummy"),job.Failure()); } else { item.NewChild("esmanag:EstimatedTime") = Arc::tostring(config.GmConfig().WakeupPeriod()); }; }; }; return Arc::MCC_Status(Arc::STATUS_OK); }
Arc::MCC_Status ARexService::ESCancelActivity(ARexGMConfig& config,Arc::XMLNode in,Arc::XMLNode out) { /* CancelActivity estypes:ActivityID 1- CancelActivityResponse CancelActivityResponseItem 1- estypes:ActivityID . EstimatedTime 0-1 estypes:InternalBaseFault OperationNotPossibleFault OperationNotAllowedFault ActivityNotFoundFault AccessControlFault estypes:VectorLimitExceededFault estypes:AccessControlFault estypes:InternalBaseFault */ Arc::XMLNode id = in["ActivityID"]; unsigned int n = 0; for(;(bool)id;++id) { if((++n) > MAX_ACTIVITIES) { Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,""); ESVectorLimitExceededFault(fault,MAX_ACTIVITIES,"Too many ActivityID"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; }; id = in["ActivityID"]; for(;(bool)id;++id) { std::string jobid = id; Arc::XMLNode item = out.NewChild("esmanag:CancelActivityResponseItem"); item.NewChild("estypes:ActivityID") = jobid; ARexJob job(jobid,config,logger_); if(!job) { // There is no such job logger_.msg(Arc::ERROR, "EMIES:CancelActivity: job %s - %s", jobid, job.Failure()); ESActivityNotFoundFault(item.NewChild("dummy"),job.Failure()); } else { if(!job.Cancel()) { // Probably wrong current state logger_.msg(Arc::ERROR, "EMIES:CancelActivity: job %s - %s", jobid, job.Failure()); // TODO: check for real reason ESOperationNotAllowedFault(item.NewChild("dummy"),job.Failure()); } else { // It may take "wakeup period" for cancel mark to be detected. // And same time till result of cancel script is processed. // Currently it is not possible to estimate how long canceling // would happen. item.NewChild("esmanag:EstimatedTime") = Arc::tostring(config.GmConfig().WakeupPeriod()*2); }; }; }; return Arc::MCC_Status(Arc::STATUS_OK); }
Arc::MCC_Status ARexService::ESResumeActivity(ARexGMConfig& config,Arc::XMLNode in,Arc::XMLNode out) { /* ResumeActivity estypes:ActivityID 1- ResumeActivityResponse ResumeActivityResponseItem 1- estypes:ActivityID . EstimatedTime 0-1 estypes:InternalBaseFault OperationNotPossibleFault OperationNotAllowedFault ActivityNotFoundFault AccessControlFault estypes:VectorLimitExceededFault estypes:AccessControlFault estypes:InternalBaseFault */ Arc::XMLNode id = in["ActivityID"]; unsigned int n = 0; for(;(bool)id;++id) { if((++n) > MAX_ACTIVITIES) { Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,""); ESVectorLimitExceededFault(fault,MAX_ACTIVITIES,"Too many ActivityID"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; }; id = in["ActivityID"]; for(;(bool)id;++id) { std::string jobid = id; Arc::XMLNode item = out.NewChild("esmanag:ResumeActivityResponseItem"); item.NewChild("estypes:ActivityID") = jobid; ARexJob job(jobid,config,logger_); if(!job) { // There is no such job logger_.msg(Arc::ERROR, "EMIES:ResumeActivity: job %s - %s", jobid, job.Failure()); ESActivityNotFoundFault(item.NewChild("dummy"),job.Failure()); } else { // Pause not implemented hence job can't be resumed too logger_.msg(Arc::ERROR, "EMIES:ResumeActivity: job %s - %s", jobid, "pause not implemented"); ESOperationNotAllowedFault(item.NewChild("dummy"),"pause not implemented"); }; }; return Arc::MCC_Status(Arc::STATUS_OK); }
Arc::MCC_Status ARexService::MigrateActivity(ARexGMConfig& config,Arc::XMLNode in,Arc::XMLNode out,const std::string& clientid) { /* MigrateActivity ActivityIdentifier (wsa:EndpointReferenceType) ActivityDocument jsdl:JobDefinition ForceMigration MigrateActivityResponse ActivityIdentifier (wsa:EndpointReferenceType) ActivityDocument jsdl:JobDefinition NotAuthorizedFault NotAcceptingNewActivitiesFault UnsupportedFeatureFault InvalidRequestMessageFault */ { std::string s; in.GetXML(s); logger_.msg(Arc::VERBOSE, "MigrateActivity: request = \n%s", s); }; Arc::WSAEndpointReference id(in["ActivityIdentifier"]); if(!(Arc::XMLNode)id) { // Wrong request logger_.msg(Arc::ERROR, "MigrateActivitys: no ActivityIdentifier found"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find ActivityIdentifier element in request"); InvalidRequestMessageFault(fault,"jsdl:ActivityIdentifier","Element is missing"); out.Destroy(); return Arc::MCC_Status(); }; std::string migrateid = Arc::WSAEndpointReference(id).Address() + "/" + (std::string)Arc::WSAEndpointReference(id).ReferenceParameters()["a-rex:JobID"]; if(migrateid.empty()) { // EPR is wrongly formated or not an A-REX EPR logger_.msg(Arc::ERROR, "MigrateActivity: EPR contains no JobID"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find JobID element in ActivityIdentifier"); InvalidRequestMessageFault(fault,"a-rex:JobID","Element is missing"); out.Destroy(); return Arc::MCC_Status(); }; // HPC Basic Profile 1.0 comply (these fault handlings are defined in the KnowARC standards // conformance roadmap 2nd release) // End of the HPC BP 1.0 fault handling part std::string delegation; Arc::XMLNode delegated_token = in["arcdeleg:DelegatedToken"]; if(delegated_token) { // Client wants to delegate credentials if(!delegation_stores_.DelegatedToken(config.GmConfig().DelegationDir(),delegated_token,config.GridName(),delegation)) { // Failed to accept delegation (report as bad request) logger_.msg(Arc::ERROR, "MigrateActivity: Failed to accept delegation"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Failed to accept delegation"); InvalidRequestMessageFault(fault,"arcdeleg:DelegatedToken","This token does not exist"); out.Destroy(); return Arc::MCC_Status(); }; }; if( !(in["ActivityDocument"]["JobDefinition"])) { /* // First try to get job desc from old cluster logger_.msg(Arc::VERBOSE, "MigrateActivity: no job description found try to get it from old cluster"); Arc::MCCConfig cfg; // TODO: //if (!proxyPath.empty()) cfg.AddProxy(delegation); //if (!certificatePath.empty()) //cfg.AddCertificate(certificatePath); //if (!keyPath.empty()) //cfg.AddPrivateKey(keyPath); //if (!caCertificatesDir.empty()) //cfg.AddCADir(caCertificatesDir); Arc::URL url(migrateid); Arc::PathIterator pi(url.Path(), true); url.ChangePath(*pi); Arc::AREXClient ac(url, cfg); Arc::NS ns; ns["a-rex"] = "http://www.nordugrid.org/schemas/a-rex"; ns["bes-factory"] = "http://schemas.ggf.org/bes/2006/08/bes-factory"; ns["wsa"] = "http://www.w3.org/2005/08/addressing"; ns["jsdl"] = "http://schemas.ggf.org/jsdl/2005/11/jsdl"; ns["jsdl-posix"] = "http://schemas.ggf.org/jsdl/2005/11/jsdl-posix"; ns["jsdl-arc"] = "http://www.nordugrid.org/ws/schemas/jsdl-arc"; ns["jsdl-hpcpa"] = "http://schemas.ggf.org/jsdl/2006/07/jsdl-hpcpa"; Arc::XMLNode id(ns, "ActivityIdentifier"); id.NewChild("wsa:Address") = url.str(); id.NewChild("wsa:ReferenceParameters").NewChild("a-rex:JobID") = pi.Rest(); std::string idstr; id.GetXML(idstr); std::string desc_str; if (ac.getdesc(idstr,desc_str)){ Arc::JobDescription desc; desc.setSource(desc_str); if (desc.isValid()) { logger_.msg(Arc::INFO,"Valid job description obtained"); if ( !( in["ActivityDocument"] ) ) in.NewChild("bes-factory:ActivityDocument"); Arc::XMLNode XMLdesc; desc.getXML(XMLdesc); in["ActivityDocument"].NewChild(XMLdesc); } else { // Wrongly formatted job description logger_.msg(Arc::ERROR, "MigrateActivity: job description could not be fetch from old cluster"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find JobDefinition element in request"); InvalidRequestMessageFault(fault,"jsdl:JobDefinition","Element is missing"); out.Destroy(); return Arc::MCC_Status(); } } */ //else { // Not able to get job description logger_.msg(Arc::ERROR, "MigrateActivity: no job description found"); //logger_.msg(Arc::ERROR, "MigrateActivity: job description could not be fetch from old cluster"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find JobDefinition element in request"); InvalidRequestMessageFault(fault,"jsdl:JobDefinition","Element is missing"); out.Destroy(); return Arc::MCC_Status(); //} }; Arc::XMLNode jsdl = in["ActivityDocument"]["JobDefinition"]; Arc::NS ns; // Creating migration XMLNode Arc::XMLNode migration(ns, "Migration"); migration.NewChild("ActivityIdentifier") = migrateid; if( (bool)in["ForceMigration"]){ migration.NewChild("ForceMigration") = (std::string)in["ForceMigration"]; } else { migration.NewChild("ForceMigration") = "true"; } std::string migrationStr; migration.GetDoc(migrationStr, true); logger_.msg(Arc::INFO, "Migration XML sent to AREXJob: %s", migrationStr); JobIDGeneratorARC idgenerator(config.Endpoint()); ARexJob job(jsdl,config,delegation,clientid,logger_,idgenerator,migration); if(!job) { ARexJobFailure failure_type = job; std::string failure = job.Failure(); switch(failure_type) { case ARexJobDescriptionUnsupportedError: { Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Unsupported feature in job description"); UnsupportedFeatureFault(fault,failure); }; break; case ARexJobDescriptionMissingError: { Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Missing needed element in job description"); UnsupportedFeatureFault(fault,failure); }; break; case ARexJobDescriptionLogicalError: { std::string element; std::string::size_type pos = failure.find(' '); if(pos != std::string::npos) { element=failure.substr(0,pos); failure=failure.substr(pos+1); }; Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Logical error in job description"); InvalidRequestMessageFault(fault,element,failure); }; break; default: { logger_.msg(Arc::ERROR, "MigrateActivity: Failed to migrate new job: %s",failure); // Failed to migrate new job (no corresponding BES fault defined - using generic SOAP error) logger_.msg(Arc::ERROR, "MigrateActivity: Failed to migrate new job"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,("Failed to migrate new activity: "+failure).c_str()); GenericFault(fault); }; break; }; out.Destroy(); return Arc::MCC_Status(); }; // Make SOAP response Arc::WSAEndpointReference identifier(out.NewChild("bes-factory:ActivityIdentifier")); // Make job's ID identifier.Address(config.Endpoint()); // address of service identifier.ReferenceParameters().NewChild("a-rex:JobID")=job.ID(); identifier.ReferenceParameters().NewChild("a-rex:JobSessionDir")=config.Endpoint()+"/"+job.ID(); out.NewChild(in["ActivityDocument"]); logger_.msg(Arc::VERBOSE, "MigrateActivity finished successfully"); { std::string s; out.GetXML(s); logger_.msg(Arc::VERBOSE, "MigrateActivity: response = \n%s", s); }; /* Needs to kill old job */ return Arc::MCC_Status(Arc::STATUS_OK); }
Arc::MCC_Status ARexService::ChangeActivityStatus(ARexGMConfig& config,Arc::XMLNode in,Arc::XMLNode out) { /* ChangeActivityStatus ActivityIdentifier (wsa:EndpointReferenceType) OldStatus (a-rex,optional) attribute = state (bes-factory:ActivityStateEnumeration) NewStatus (a-rex) attribute = state (bes-factory:ActivityStateEnumeration) ChangeActivityStatusResponse NewStatus (a-rex) attribute = state (bes-factory:ActivityStateEnumeration) NotAuthorizedFault InvalidActivityIdentifierFault CantApplyOperationToCurrentStateFault */ { std::string s; in.GetXML(s); logger_.msg(Arc::VERBOSE, "ChangeActivityStatus: request = \n%s", s); }; Arc::WSAEndpointReference id(in["ActivityIdentifier"]); if(!(Arc::XMLNode)id) { // Wrong request logger_.msg(Arc::ERROR, "ChangeActivityStatus: no ActivityIdentifier found"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find ActivityIdentifier element in request"); InvalidRequestMessageFault(fault,"jsdl:ActivityIdentifier","Element is missing"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; std::string jobid = Arc::WSAEndpointReference(id).ReferenceParameters()["a-rex:JobID"]; if(jobid.empty()) { // EPR is wrongly formated or not an A-REX EPR logger_.msg(Arc::ERROR, "ChangeActivityStatus: EPR contains no JobID"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find JobID element in ActivityIdentifier"); InvalidRequestMessageFault(fault,"a-rex:JobID","Element is missing"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; ARexJob job(jobid,config,logger_); if(!job) { // There is no such job std::string failure = job.Failure(); logger_.msg(Arc::ERROR, "ChangeActivityStatus: no job found: %s",failure); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find requested Activity"); UnknownActivityIdentifierFault(fault,"No corresponding Activity found"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; // Old State Arc::XMLNode old_state = in["OldStatus"]; std::string old_bes_state = old_state.Attribute("state"); std::string old_arex_state = old_state["a-rex:state"]; // New state Arc::XMLNode new_state = in["NewStatus"]; if(!new_state) { // Wrong request logger_.msg(Arc::ERROR, "ChangeActivityStatus: missing NewStatus element"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Missing NewStatus element in request"); InvalidRequestMessageFault(fault,"a-rex:NewStatus","Element is missing"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; std::string new_bes_state = new_state.Attribute("state"); std::string new_arex_state = new_state["a-rex:state"]; // Take renewed proxy if supplied std::string delegation; Arc::XMLNode delegated_token = new_state["arcdeleg:DelegatedToken"]; if(delegated_token) { if(!delegation_stores_.DelegatedToken(config.GmConfig().DelegationDir(),delegated_token,config.GridName(),delegation)) { // Failed to accept delegation (report as bad request) logger_.msg(Arc::ERROR, "ChangeActivityStatus: Failed to accept delegation"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Failed to accept delegation"); InvalidRequestMessageFault(fault,"arcdeleg:DelegatedToken","This token does not exist"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; }; bool pending = false; std::string gm_state = job.State(pending); bool failed = job.Failed(); std::string bes_state(""); std::string arex_state(""); convertActivityStatus(gm_state,bes_state,arex_state,failed,pending); // Old state in request must be checked against current one if((!old_bes_state.empty()) && (old_bes_state != bes_state)) { logger_.msg(Arc::ERROR, "ChangeActivityStatus: old BES state does not match"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"OldStatus is not same as current status"); CantApplyOperationToCurrentStateFault(fault,gm_state,failed,"OldStatus does not match"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; if((!old_arex_state.empty()) && (old_arex_state != arex_state)) { logger_.msg(Arc::ERROR, "ChangeActivityStatus: old A-REX state does not match"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"OldStatus is not same as current status"); CantApplyOperationToCurrentStateFault(fault,gm_state,failed,"OldStatus does not match"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; // Check for allowed combinations if((new_bes_state == "Finished") && ((new_arex_state.empty()) || (new_arex_state == "Killing"))) { // Request to cancel job if((gm_state != "FINISHED") && (gm_state != "CANCELING") && (gm_state != "DELETED")) job.Cancel(); } else if((new_bes_state == "Finished") && (new_arex_state == "Deleted")) { // Request to clean job if((gm_state != "FINISHED") && (gm_state != "CANCELING") && (gm_state != "DELETED")) job.Cancel(); job.Clean(); } else if((new_bes_state == "Running") && (new_arex_state.empty())) { // Not supporting resume into user-defined state // Request to resume job if(!job.UpdateCredentials(delegation)) { logger_.msg(Arc::ERROR, "ChangeActivityStatus: Failed to update credentials"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Internal error: Failed to update credentials"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; if(!job.Resume()) { logger_.msg(Arc::ERROR, "ChangeActivityStatus: Failed to resume job"); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Internal error: Failed to resume activity"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; } else { logger_.msg(Arc::ERROR, "ChangeActivityStatus: State change not allowed: from %s/%s to %s/%s", bes_state.c_str(),arex_state.c_str(),new_bes_state.c_str(),new_arex_state.c_str()); Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Requested status transition is not supported"); CantApplyOperationToCurrentStateFault(fault,gm_state,failed,"Requested status transition is not supported"); out.Destroy(); return Arc::MCC_Status(Arc::STATUS_OK); }; // Make response // TODO: // Updating currenst job state gm_state=job.State(pending); failed=job.Failed(); convertActivityStatus(gm_state,bes_state,arex_state,failed,pending); Arc::XMLNode state = out.NewChild("a-rex:NewStatus"); state.NewAttribute("bes-factory:state")=bes_state; state.NewChild("a-rex:state")=arex_state; { std::string s; out.GetXML(s); logger_.msg(Arc::VERBOSE, "ChangeActivityStatus: response = \n%s", s); }; return Arc::MCC_Status(Arc::STATUS_OK); }