/** * \brief The getJobOutput function gets outputPath and errorPath of a job from its id * \param sessionKey : The session key * \param jobId : The Id of the job * \param outputInfo : The Job object containing the job output information (e.g: outputPath and errorPath) of the job to submit * \param options : Object containing the user-provided options (e.g: it contains a possible output directory set by the user) * \return 0 on success, or raises exception on error */ int vishnu::getJobOutput(const std::string& sessionKey, const std::string& jobId, TMS_Data::JobResult& outputInfo, const TMS_Data::JobOutputOptions& options) throw (UMSVishnuException, TMSVishnuException, UserException, SystemException) { checkEmptyString(sessionKey, "The session key"); std::string outputDir = options.getOutputDir(); if (! outputDir.empty() && ! boost::filesystem::exists(outputDir)) { throw UMSVishnuException(ERRCODE_INVALID_PARAM, "The output directory does not exist: "+ outputDir); } // If no machine id provided, find where the job has been submitted std::string machineId = options.getMachineId(); if (machineId.empty()) { TMS_Data::Job jobInfo; getJobInfo(sessionKey, jobId, machineId, jobInfo); machineId = jobInfo.getMachine(); } // Now process the request SessionProxy sessionProxy(sessionKey); JobOutputProxy jobOutputProxy(sessionProxy, machineId); outputInfo = jobOutputProxy.getJobOutPut(jobId, options); return 0; }
int main (int argc, char* argv[]){ /******* Parsed value containers ****************/ std::string configFile; std::string sessionKey; std::string machineId; std::string outputDir; int forceDownloadDays = -1; /**************** Describe options *************/ boost::shared_ptr<Options> opt (new Options(argv[0])); // Environement option opt->add("configFile,c", "VISHNU configuration file", ENV, configFile); opt->add("sessionkey,k", "VISHNU session key to connect", ENV, sessionKey); // Other options opt->add("machineId,m", "The target machine", CONFIG, machineId); opt->add("outDir,o", "The outputh dir of the jobs results", CONFIG, outputDir); opt->add("days,d", "Considers jobs submitted in the last <days> days", CONFIG, forceDownloadDays); // Process the options bool isEmpty; GenericCli().processListOpt(opt, isEmpty, argc, argv); TMS_Data::JobOutputOptions options; options.setMachineId(machineId); options.setOutputDir(outputDir); options.setDays(forceDownloadDays); // Process the command JobResultsFunc jobResultsFunc(options); return GenericCli().run(jobResultsFunc, configFile, argc, argv, sessionKey); }
/** * \brief Gets standard output files of all completed jobs (applies only once for each job) * \param sessionKey : The session key * \param options: object containing options * \param listOfResults : Is the list of jobs results * \param options: Object containing options * \return int : an error code */ int vishnu::getCompletedJobsOutput(const std::string& sessionKey, TMS_Data::ListJobResults& listOfResults, const TMS_Data::JobOutputOptions& options) throw (UMSVishnuException, TMSVishnuException, UserException, SystemException) { checkEmptyString(sessionKey, "The session key"); std::string outputDir = options.getOutputDir(); if (! outputDir.empty() && ! boost::filesystem::exists(outputDir)) { throw UMSVishnuException(ERRCODE_INVALID_PARAM, "The ouput directory does not exist: "+outputDir); } UMS_Data::ListMachines machines; if (options.getMachineId().empty()) { vishnu::listMachinesWithUserLocalAccount(sessionKey, machines); } else { UMS_Data::Machine_ptr machine = new UMS_Data::Machine(); // delete by EMF machine->setMachineId(options.getMachineId()); machines.getMachines().push_back(machine); } int machineCount = machines.getMachines().size(); for (int index = 0; index < machineCount; ++index) { SessionProxy sessionProxy(sessionKey); JobOutputProxy jobOutputProxy(sessionProxy, machines.getMachines().get(index)->getMachineId()); TMS_Data::ListJobResults_ptr listJobResults_ptr = jobOutputProxy.getCompletedJobsOutput(options); if (listJobResults_ptr != NULL) { TMS_Data::TMS_DataFactory_ptr ecoreFactory = TMS_Data::TMS_DataFactory::_instance(); for(unsigned int i = 0; i < listJobResults_ptr->getResults().size(); i++) { TMS_Data::JobResult_ptr jobResult = ecoreFactory->createJobResult(); //To copy the content and not the pointer *jobResult = *listJobResults_ptr->getResults().get(i); listOfResults.getResults().push_back(jobResult); } listOfResults.setNbJobs(listJobResults_ptr->getNbJobs()); delete listJobResults_ptr; } } return 0; }
/** * \brief Function to get the job results * \param jobId The Id of the * \param options Object containing the user-provided options * \return The job results data structure */ TMS_Data::JobResult JobOutputProxy::getJobOutPut(const std::string& jobId, const TMS_Data::JobOutputOptions& options) { std::string serviceName = boost::str(boost::format("%1%@%2%") % SERVICES_TMS[JOBOUTPUTGETRESULT] %mmachineId); diet_profile_t* profile = diet_profile_alloc(serviceName, 4); string sessionKey = msessionProxy.getSessionKey(); //IN Parameters TMS_Data::JobResult jobResult; jobResult.setJobId(jobId); std::string outputDir = options.getOutputDir(); JsonObject optionsData(options); diet_string_set(profile,0, sessionKey); diet_string_set(profile,1, mmachineId); diet_string_set(profile,2, optionsData.encode()); diet_string_set(profile, 3, jobId); //Call the Server if (diet_call(profile)) { raiseCommunicationMsgException("RPC call failed"); } raiseExceptionOnErrorResult(profile); std::string remoteOutputInfo; diet_string_get(profile,1, remoteOutputInfo); if (remoteOutputInfo.empty()) { throw TMSVishnuException(ERRCODE_INVDATA, "Weird behavior: no output to retrieve"); } if (! boost::starts_with(remoteOutputInfo, "/") ) { raiseExceptionIfNotEmptyMsg(remoteOutputInfo); } if (outputDir.empty()) { outputDir = boost::str(boost::format("%1%/VISHNU_DOWNLOAD_%2%") % bfs::path(bfs::current_path()).string() % vishnu::generatedUniquePatternFromCurTime(jobId)); vishnu::createOutputDir(outputDir); } jobResult.setOutputDir(outputDir); FMS_Data::CpFileOptions copts; copts.setIsRecursive(true); copts.setTrCommand(0); // for using scp try { std::string downloadInfoFile = boost::str(boost::format("%1%/%2%") % outputDir % boost::filesystem::unique_path("vishnu-%%%%%%.dinfo").string()); vishnu::genericFileCopier(sessionKey, mmachineId, remoteOutputInfo, "", downloadInfoFile, copts); istringstream fdescStream(vishnu::get_file_content(downloadInfoFile, false)); string line; if(! getline(fdescStream, line)) { line = ""; } boost::trim(line); ListStrings lineVec; boost::split(lineVec, line, boost::is_any_of(" ")); int nbFiles = lineVec.size(); std::string missingFileContent = ""; if (! line.empty() && nbFiles > 0) { vishnu::copyFiles(sessionKey, mmachineId, lineVec, outputDir, copts, missingFileContent, 0); std::string fileName = bfs::basename(lineVec[0]) + bfs::extension(lineVec[0]); jobResult.setOutputPath(outputDir+"/"+fileName); std::string fileName2 = bfs::basename(lineVec[1]) + bfs::extension(lineVec[1]); jobResult.setErrorPath(outputDir+"/"+fileName2); } if (! missingFileContent.empty()) { std::string missingFileName = (boost::format("%1%/MISSINGFILES_%2%") % outputDir % jobId).str(); vishnu::saveInFile(missingFileName, missingFileContent); } } catch (VishnuException &ex) { std::string errorFileName = (boost::format("%1%/ERROR_%2%") % outputDir % jobId).str(); vishnu::saveInFile(errorFileName, ex.what()); } diet_profile_free(profile); return jobResult; }
/** * \brief Function to get the results of all job submitted * \return The list of the job results */ TMS_Data::ListJobResults_ptr JobOutputProxy::getCompletedJobsOutput(const TMS_Data::JobOutputOptions& options) { std::string serviceName = boost::str(boost::format("%1%@%2%") % SERVICES_TMS[JOBOUTPUTGETCOMPLETEDJOBS] % mmachineId); diet_profile_t* profile = diet_profile_alloc(serviceName, 3); std::string sessionKey = msessionProxy.getSessionKey(); JsonObject optionsData(options); //IN Parameters if (diet_string_set(profile,0, sessionKey)) { raiseCommunicationMsgException("Exception setting sessionkey parameter"); } if (diet_string_set(profile, 1, mmachineId)) { raiseCommunicationMsgException("Exception setting machineid parameter"); } if (diet_string_set(profile, 2, optionsData.encode())) { raiseCommunicationMsgException("Exception setting option parameter"); } //Call the Server if (diet_call(profile)) { raiseCommunicationMsgException("RPC call failed"); } raiseExceptionOnErrorResult(profile); // Get output, which is a json object. See internalApi.cpp std::string data; diet_string_get(profile,1, data); // Treat the json object JsonObject jsonData(data); std::string remoteOutputInfo = jsonData.getStringProperty("infofile"); std::string jobListSerialized = jsonData.getStringProperty("joblist"); if (remoteOutputInfo.empty() || ! boost::starts_with(remoteOutputInfo, "/")) { throw TMSVishnuException(ERRCODE_INVDATA, boost::str(boost::format("Weird output info file [%1%]" ) % remoteOutputInfo)); } TMS_Data::ListJobResults_ptr listJobResults_ptr = NULL; parseEmfObject(jobListSerialized, listJobResults_ptr); FMS_Data::CpFileOptions copts; copts.setIsRecursive(true); copts.setTrCommand(0); // for using scp std::string outputDir = options.getOutputDir(); try { std::string downloadInfoFile = boost::str(boost::format("%1%/%2%") % boost::filesystem::temp_directory_path().string() % boost::filesystem::unique_path("vishnu-%%%%%%.dinfo").string()); vishnu::genericFileCopier(sessionKey, mmachineId, remoteOutputInfo, "", downloadInfoFile, copts); istringstream downloadInfoStream (vishnu::get_file_content(downloadInfoFile, false)); int numJob = 0; string line; ListStrings lineVec; string missingFiles; while (getline(downloadInfoStream, line)) { if (line.empty()) continue; boost::trim(line); boost::split(lineVec, line, boost::is_any_of(" ")); std::string baseDir = (! outputDir.empty())? bfs::absolute(outputDir).string() : bfs::path(bfs::current_path()).string(); std::string targetDir = boost::str(boost::format("%1%/VISHNU_DOWNLOAD_%2%") % baseDir % vishnu::generatedUniquePatternFromCurTime(lineVec[0])); vishnu::createOutputDir(targetDir); vishnu::copyFiles(sessionKey, mmachineId, lineVec, targetDir, copts, missingFiles, 1); listJobResults_ptr->getResults().get(numJob++)->setOutputDir(targetDir); if (!missingFiles.empty()) { vishnu::saveInFile(targetDir+"/MISSINGFILES", missingFiles); } } } catch (FMSVishnuException &ex) { vishnu::saveInFile(outputDir+"/ERROR", boost::str(boost::format("File %1%: %2%") % remoteOutputInfo % ex.what())); } diet_profile_free(profile); return listJobResults_ptr; }