예제 #1
0
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);
}
예제 #2
0
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);
}