Back to index

nordugrid-arc-nox  1.1.0~rc6
change_activity_status.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <arc/message/SOAPEnvelope.h>
00006 #include <arc/ws-addressing/WSA.h>
00007 #include "job.h"
00008 #include "tools.h"
00009 
00010 #include "arex.h"
00011 
00012 namespace ARex {
00013 
00014 
00015 Arc::MCC_Status ARexService::ChangeActivityStatus(ARexGMConfig& config,Arc::XMLNode in,Arc::XMLNode out) {
00016   /*
00017   ChangeActivityStatus
00018     ActivityIdentifier (wsa:EndpointReferenceType)
00019     OldStatus (a-rex,optional)
00020         attribute = state (bes-factory:ActivityStateEnumeration)
00021     NewStatus (a-rex)
00022         attribute = state (bes-factory:ActivityStateEnumeration)
00023 
00024   ChangeActivityStatusResponse
00025     NewStatus (a-rex)
00026         attribute = state (bes-factory:ActivityStateEnumeration)
00027 
00028   NotAuthorizedFault
00029   InvalidActivityIdentifierFault
00030   CantApplyOperationToCurrentStateFault
00031   */
00032   {
00033     std::string s;
00034     in.GetXML(s);
00035     logger_.msg(Arc::VERBOSE, "ChangeActivityStatus: request = \n%s", s);
00036   };
00037   Arc::WSAEndpointReference id(in["ActivityIdentifier"]);
00038   if(!(Arc::XMLNode)id) {
00039     // Wrong request
00040     logger_.msg(Arc::ERROR, "ChangeActivityStatus: no ActivityIdentifier found");
00041     Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find ActivityIdentifier element in request");
00042     InvalidRequestMessageFault(fault,"jsdl:ActivityIdentifier","Element is missing");
00043     out.Destroy();
00044     return Arc::MCC_Status();
00045   };
00046   std::string jobid = Arc::WSAEndpointReference(id).ReferenceParameters()["a-rex:JobID"];
00047   if(jobid.empty()) {
00048     // EPR is wrongly formated or not an A-REX EPR
00049     logger_.msg(Arc::ERROR, "ChangeActivityStatus: EPR contains no JobID");
00050     Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find JobID element in ActivityIdentifier");
00051     InvalidRequestMessageFault(fault,"a-rex:JobID","Element is missing");
00052     out.Destroy();
00053     return Arc::MCC_Status();
00054   };
00055   ARexJob job(jobid,config,logger_);
00056   if(!job) {
00057     // There is no such job
00058     std::string failure = job.Failure();
00059     logger_.msg(Arc::ERROR, "ChangeActivityStatus: no job found: %s",failure);
00060     Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Can't find requested Activity");
00061     UnknownActivityIdentifierFault(fault,"No corresponding Activity found");
00062     out.Destroy();
00063     return Arc::MCC_Status();
00064   };
00065 
00066   // Old State
00067   Arc::XMLNode old_state = in["OldStatus"];
00068   std::string old_bes_state = old_state.Attribute("state");
00069   std::string old_arex_state = old_state["a-rex:state"];
00070 
00071   // New state
00072   Arc::XMLNode new_state = in["NewStatus"];
00073   if(!new_state) {
00074     // Wrong request
00075     logger_.msg(Arc::ERROR, "ChangeActivityStatus: missing NewStatus element");
00076     Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Missing NewStatus element in request");
00077     InvalidRequestMessageFault(fault,"a-rex:NewStatus","Element is missing");
00078     out.Destroy();
00079     return Arc::MCC_Status();
00080   };
00081   std::string new_bes_state = new_state.Attribute("state");
00082   std::string new_arex_state = new_state["a-rex:state"];
00083   // Take renewed proxy if supplied
00084   std::string delegation;
00085   Arc::XMLNode delegated_token = new_state["deleg:DelegatedToken"];
00086   if(delegated_token) {
00087     if(!delegations_.DelegatedToken(delegation,delegated_token)) {
00088       // Failed to accept delegation (report as bad request)
00089       logger_.msg(Arc::ERROR, "ChangeActivityStatus: Failed to accept delegation");
00090       Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Failed to accept delegation");
00091       InvalidRequestMessageFault(fault,"deleg:DelegatedToken","This token does not exist");
00092       out.Destroy();
00093       return Arc::MCC_Status();
00094     };
00095   };
00096 
00097   bool pending = false;
00098   std::string gm_state = job.State(pending);
00099   bool failed = job.Failed();
00100   std::string bes_state("");
00101   std::string arex_state("");
00102   convertActivityStatus(gm_state,bes_state,arex_state,failed,pending);
00103   // Old state in request must be checked against current one
00104   if((!old_bes_state.empty()) && (old_bes_state != bes_state)) {
00105     logger_.msg(Arc::ERROR, "ChangeActivityStatus: old BES state does not match");
00106     Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"OldStatus is not same ass current status");
00107     CantApplyOperationToCurrentStateFault(fault,gm_state,failed,"OldStatus does not match");
00108     out.Destroy();
00109     return Arc::MCC_Status();
00110   };
00111   if((!old_arex_state.empty()) && (old_arex_state != arex_state)) {
00112     logger_.msg(Arc::ERROR, "ChangeActivityStatus: old A-Rex state does not match");
00113     Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"OldStatus is not same ass current status");
00114     CantApplyOperationToCurrentStateFault(fault,gm_state,failed,"OldStatus does not match");
00115     out.Destroy();
00116     return Arc::MCC_Status();
00117   };
00118 
00119   // Check for allowed combinations
00120   if((new_bes_state == "Finished") &&
00121      ((new_arex_state.empty()) || (new_arex_state == "Killing"))) {
00122     // Request to cancel job
00123     if((gm_state != "FINISHED") &&
00124        (gm_state != "CANCELING") &&
00125        (gm_state != "DELETED")) job.Cancel();
00126   } else
00127   if((new_bes_state == "Finished") &&
00128      (new_arex_state == "Deleted")) {
00129      // Request to clean job
00130     if((gm_state != "FINISHED") &&
00131        (gm_state != "CANCELING") &&
00132        (gm_state != "DELETED")) job.Cancel();
00133     job.Clean();
00134   } else 
00135   if((new_bes_state == "Running") &&
00136      (new_arex_state.empty())) { // Not supporting resume into user-defined state
00137     // Request to resume job
00138     if(!job.UpdateCredentials(delegation)) {
00139       logger_.msg(Arc::ERROR, "ChangeActivityStatus: failed to update credentials");
00140       Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Internal error: Failed to update credentials");
00141       out.Destroy();
00142       return Arc::MCC_Status();
00143     };
00144     if(!job.Resume()) {
00145       logger_.msg(Arc::ERROR, "ChangeActivityStatus: failed to resume job");
00146       Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Internal error: Failed to resume activity");
00147       out.Destroy();
00148       return Arc::MCC_Status();
00149     };
00150   } else {
00151     logger_.msg(Arc::ERROR, "ChangeActivityStatus: state change not allowed: from %s/%s to %s/%s",
00152                 bes_state.c_str(),arex_state.c_str(),new_bes_state.c_str(),new_arex_state.c_str());
00153     Arc::SOAPFault fault(out.Parent(),Arc::SOAPFault::Sender,"Requested status transition is not supported");
00154     CantApplyOperationToCurrentStateFault(fault,gm_state,failed,"Requested status transition is not supported");
00155     out.Destroy();
00156     return Arc::MCC_Status();
00157   };
00158   // Make response
00159   // TODO: 
00160   // Updating currenst job state
00161   gm_state=job.State(pending);
00162   failed=job.Failed();
00163   convertActivityStatus(gm_state,bes_state,arex_state,failed,pending);
00164   Arc::XMLNode state = out.NewChild("a-rex:NewStatus");
00165   state.NewAttribute("bes-factory:state")=bes_state;
00166   state.NewChild("a-rex:state")=arex_state;
00167   {
00168     std::string s;
00169     out.GetXML(s);
00170     logger_.msg(Arc::VERBOSE, "ChangeActivityStatus: response = \n%s", s);
00171   };
00172   return Arc::MCC_Status(Arc::STATUS_OK);
00173 }
00174 
00175 } // namespace ARex
00176