// @(#)root/net:$Id$ // Author: Volodymyr Yurchenko 01/12/2016 /************************************************************************* * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "TJAlien.h" ClassImp(TJAlien) TString TJAlien::fPwd = TString(""); //______________________________________________________________________________ TJAlien::TJAlien (const char* gridUrl, const char* uId, const char* passwd, const char* options) { fGridUrl = gridUrl; fUser = uId; fPw = passwd; fOptions = options; fGrid = "alien"; gGrid = this; if (getenv("TMPDIR") != nullptr) tmpdir = getenv("TMPDIR"); else if (getenv("TMP") != nullptr) tmpdir = getenv("TMP"); else if (getenv("TEMP") != nullptr) tmpdir = getenv("TEMP"); else tmpdir = P_tmpdir; Connect(); } //______________________________________________________________________________ void TJAlien::Connect() { TString oldfPwd(fPwd); int connection_mode = connection.CreateConnection(); if (connection_mode == -1) { // Failed to connect // TJAlienConnectionManager will produce an error message return; } else if (connection_mode == 1) { // Connected to JCentral with full grid certificate // Immediately ask for the token Token("", false); } // Run a command to initialize gGrid variables from the metadata SetSite(gSystem->Getenv("ALIEN_SITE")); fHome = fPwd; // Change to the last known location if (oldfPwd.Length() != 0) Cd(oldfPwd.Data()); } //______________________________________________________________________________ TJAlien::~TJAlien() { if (gDebug > 1) Info("TJAlien", "Destructor called"); } //______________________________________________________________________________ void TJAlien::Stderr() { if (connection.readBuffer != nullptr) { json_object * jobj_res = json_tokener_parse(connection.readBuffer.c_str()); // get metadata json_object *js_results; json_object_object_get_ex(jobj_res, "metadata", &js_results); if (js_results != nullptr && json_object_is_type(js_results, json_type_object)) { TString error_stream = json_object_get_string(json_object_object_get(js_results, "error")); if (error_stream != nullptr && error_stream.Length() != 0) printf("%s\n", error_stream.Data()); } } } //______________________________________________________________________________ void TJAlien::Stdout() { if (connection.readBuffer != nullptr) { json_object * jobj_res = json_tokener_parse(connection.readBuffer.c_str()); //Info("Stdout", "%s", TJAlien::readBuffer.c_str()); // get data from results json_object *js_results; json_object_object_get_ex(jobj_res, "results", &js_results); if (js_results != nullptr && json_object_is_type(js_results, json_type_array)) { int arraylen = json_object_array_length(js_results); int i; for (i = 0; i < arraylen; i++) { json_object *jvalue = json_object_array_get_idx(js_results, i); json_object_object_foreach(jvalue, key, val) { printf("%s\t", json_object_get_string(val)); UNUSED(key); } printf("\n"); } } } } //______________________________________________________________________________ unsigned int TJAlien::ReadTags(int column, std::map &tags) const { /** Fills the key-value pairs of a response from the server into the the associative array @tags. @column is the column of the response you are interested in. The return value is the number of tags found. */ UNUSED(column); if (connection.readBuffer != nullptr) { json_object * jobj_res = json_tokener_parse(connection.readBuffer.c_str()); // get data from results json_object *js_results; json_object_object_get_ex(jobj_res, "results", &js_results); if (js_results != nullptr && json_object_is_type(js_results, json_type_array)) { int arraylen = json_object_array_length(js_results); int i; for (i = 0; i < arraylen; i++) { Info("TJAlien", "==================="); json_object *jvalue = json_object_array_get_idx(js_results, i); json_object_object_foreach(jvalue, key, val) { tags[key] = json_object_get_string(val); } } } } return tags.size(); } //______________________________________________________________________________ TGridResult *TJAlien::Command(const char *command, bool interactive, UInt_t stream) { // TGrid Command method implementation // Command can be called directly by the user // Command format is one line, ex : ls -la // For internal usage follow RunJsonCommand method // Do not forget to delete the result after usage if (command == nullptr || std::string(command).find_first_not_of(' ') == std::string::npos) { Error("Command", "Please, specify the command"); return nullptr; } if (interactive) Info("Command", "Received full command =\"%s\"", command); UNUSED(stream); TString *sCmd = new TString(command); TObjArray *tokens = sCmd->Tokenize(" "); TJAlienResult *result; connection.readBuffer = ""; if (tokens->GetEntries() == 1) { if (interactive) Info("Command", "Received only command"); result = (TJAlienResult*) connection.RunJsonCommand(sCmd, 0); if (result) TJAlienResultRewriter().Rewrite((std::string)*sCmd, result); } else { TList *options = new TList(); TObjString *sCommand = (TObjString *) tokens->At(0); if (interactive) Info("Command", "Command = \"%s\"", sCommand->GetString().Data()); TString opt; bool append = false; for (int i = 1; i < tokens->GetEntries(); i++) { TObjString *token = (TObjString *) tokens->At(i); if (token->GetString().Contains('\"')) { if (append) { opt.Append(" "); opt.Append(Strip(token->GetString().Data(), '\"')); append = false; } else { opt = Strip(token->GetString().Data(), '\"'); append = true; if (i == tokens->GetEntries() - 1) { Error("Command", "Invalid command. Check if you miss a matching quote"); return nullptr; } continue; } } else { if (append) { opt.Append(" "); opt.Append(token->GetString().Data()); if (i == tokens->GetEntries() - 1) { Error("Command", "Invalid command. Check if you miss a matching quote"); return nullptr; } continue; } else opt = token->GetString(); } if (interactive) Info("Command", "Option = \"%s\"", opt.Data()); options->Add(new TObjString(opt)); } TString *s = new TString(sCommand->GetString()); result = (TJAlienResult*) connection.RunJsonCommand(s, options); if (result) TJAlienResultRewriter().Rewrite(sCommand->GetString().Data(), result); if (interactive) { Stdout(); Stderr(); } delete s; delete options; } delete tokens; delete sCmd; if (result) { // Extract the username, current directory, host and port // immediately after each command, since it could change TObjString p("user"); TObjString *sUserMetadata = result->GetMetaData(&p); if (sUserMetadata) { fUser = sUserMetadata->GetString(); } TObjString k("currentdir"); TObjString *sPwdMetadata = result->GetMetaData(&k); if (sPwdMetadata) { fPwd = result->GetMetaData(&k)->GetString(); } connection.GetHostAndPort(fHost, fPort); } return result; } //______________________________________________________________________________ void TJAlien::Token(Option_t* options, bool force_restart) { if (force_restart) { connection.ForceRestart(); } TString sCmd("token"); TString sOptions(options); if (sOptions.Length() > 0) sCmd += TString(" ") + sOptions; if (gDebug > 1) Info("Token", "Full command = \"%s\"", sCmd.Data()); TJAlienResult *result = (TJAlienResult*) Command(sCmd.Data()); if (result) { TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(result, errorMessage); if (exitcode != 0) { Error("Token", "%s", errorMessage->GetString().Data()); delete result; } std::stringstream tokencert_s, tokenkey_s, tokenlock_s; tokencert_s << tmpdir << "/tokencert_" << getuid() << ".pem"; tokenkey_s << tmpdir << "/tokenkey_" << getuid() << ".pem"; tokenlock_s << tmpdir << "/jalien_token_" << getuid() << ".lock"; std::string tokencert = tokencert_s.str(); std::string tokenkey = tokenkey_s.str(); std::string tokenlock = tokenlock_s.str(); std::string tokencertpath = std::getenv("JALIEN_TOKEN_CERT") ? : tokencert; std::string tokenkeypath = std::getenv("JALIEN_TOKEN_KEY") ? : tokenkey; { // Create a lock file to block other TJAlien-ROOT instances from writing to tokencert file // If a lock exists that is older than 300 seconds, the file is removed and created again. TLockFile lock(tokenlock.c_str(), 300); FILE *tokencertfile = nullptr; FILE *tokenkeyfile = nullptr; // First modify permissions if files already exist if ((tokencertfile = fopen(tokencertpath.c_str(), "r")) && (tokenkeyfile = fopen(tokenkeypath.c_str(), "r")) ) { // TODO: add a validity check here if (system(("chmod 755 " + tokencertpath).c_str())) Error("Token", "Error while accessing token files"); if (system(("chmod 755 " + tokenkeypath).c_str())) Error("Token", "Error while accessing token files"); fclose(tokencertfile); fclose(tokenkeyfile); } // Write files and restrict permissions back if ((tokencertfile = fopen(tokencertpath.c_str(), "w")) && (tokenkeyfile = fopen(tokenkeypath.c_str(), "w")) ) { fprintf(tokencertfile, "%s", result->GetKey(0, "tokencert")); fprintf(tokenkeyfile, "%s", result->GetKey(0, "tokenkey")); if (system(("chmod 440 " + tokencertpath).c_str())) Error("Token", "Error while accessing token files"); if (system(("chmod 400 " + tokenkeypath).c_str())) Error("Token", "Error while accessing token files"); fclose(tokencertfile); fclose(tokenkeyfile); } } } else { Error("Token", "RequestTokenCert: error while running command, no return result"); } return; } //______________________________________________________________________________ TGridResult *TJAlien::Ls(const char* lfn, Option_t* options, Bool_t verbose) { if (verbose) Info("Ls", "Ls command received with lfn = \"%s\" and options = \"%s\"", lfn, options); TString cmdline("ls"); TString sLfn(lfn); TString sOptions(options); if (sLfn.Length() > 0 && std::string(lfn).find_first_not_of(' ') != std::string::npos) cmdline += TString(" ") + sLfn; if (sOptions.Length() > 0) cmdline += TString(" ") + sOptions; if (gDebug > 1) Info("Ls", "Full command = \"%s\"", cmdline.Data()); TJAlienResult *result = (TJAlienResult*) Command(cmdline.Data()); if (verbose) { Stdout(); Stderr(); } if (result) { TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(result, errorMessage); if (exitcode != 0) { if (gDebug > 1) Error("Ls", "%s", errorMessage->GetString().Data()); delete result; return nullptr; } } else { if (gDebug > 1) Error("Ls", "Ls: error while running command, no return result"); return nullptr; } if (gDebug > 1) Info("Ls", "Ls command successful"); return result; } //______________________________________________________________________________ Bool_t TJAlien::Cd(const char* lfn, Bool_t verbose) { if (verbose) Info("Cd", "\"Cd\" command with argument = \"%s\"", lfn); TString cmdline("cd"); TString sLfn(lfn); if (sLfn == nullptr || sLfn.Length() == 0 || std::string(lfn).find_first_not_of(' ') == std::string::npos) sLfn = GetHomeDirectory(); cmdline += TString(" ") + sLfn; TJAlienResult *result = (TJAlienResult*) Command(cmdline.Data(), kFALSE); if (verbose) { Stdout(); Stderr(); } if (result) { TObjString *errorMessage = new TObjString(); Int_t exitcode = GetExitCode(result, errorMessage); if (exitcode != 0) { if (gDebug > 1) Error("Cd", "%s", errorMessage->GetString().Data()); delete result; return kFALSE; } else { if (gDebug > 1) Info("Cd", "Cd command successful, changed to \"%s\"", sLfn.Data()); delete result; return kTRUE; } } else { Error("Cd", "Cd: error while running command, no return result"); return kFALSE; } } //______________________________________________________________________________ Int_t TJAlien::Mkdir(const char* ldn, Option_t* option, Bool_t verbose) { // returns exitcode, what means: // 0 - if success // not 0 with error message - if sth went wrong if (ldn == nullptr || std::string(ldn).find_first_not_of(' ') == std::string::npos) { Error("Mkdir", "Command requires an argument"); return -1; } TString cmdline("mkdir"); TString sOption(option); if (sOption.Length() > 0) cmdline += TString(" ") + sOption; cmdline += (TString(" ") + TString(ldn)); TGridResult *result = Command(cmdline, kFALSE); if (verbose) { Stdout(); Stderr(); } if (result) { TJAlienResult * jalienresult = (TJAlienResult*) result; TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { if (gDebug > 1) Error("Mkdir", "Mkdir command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return exitcode; } if (gDebug > 1) Info("Mkdir", "Mkdir command successful, created directory \"%s\"", ldn); delete result; return exitcode; } Error("Mkdir", "Cannot create directory %s", ldn); if (!verbose) Stdout(); return 1; } //______________________________________________________________________________ Bool_t TJAlien::Rmdir(const char* ldn, Option_t* options, Bool_t verbose) { if (ldn == nullptr || std::string(ldn).find_first_not_of(' ') == std::string::npos) { Error("Rmdir", "Command requires an argument"); return -1; } TString cmdline = TString("rmdir "); if (strlen(options)) { cmdline += TString(options); } else { cmdline += TString(ldn); } TGridResult *result = Command(cmdline, kFALSE); if (verbose) { Stdout(); Stderr(); } if (result) { TJAlienResult *jalienresult = (TJAlienResult *) result; TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { if (gDebug > 1) Error("Rmdir", "Rmdir command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return kFALSE; } else { if (gDebug > 1) Info("Rmdir", "Rmdir command successful, removed directory \"%s\"", ldn); delete result; return kTRUE; } } if (gDebug > 1) Error("Rmdir","Cannot remove directory %s",ldn); return kFALSE; } //______________________________________________________________________________ Bool_t TJAlien::Register(const char* lfn, const char* turl, Long_t size, const char* se, const char* guid, Bool_t verbose) { UNUSED(lfn); UNUSED(turl); UNUSED(size); UNUSED(se); UNUSED(guid); UNUSED(verbose); (dynamic_cast (gGrid))->NotImplemented(__func__, __FILE__, __LINE__); return kFALSE; /* if (lfn == nullptr || std::string(lfn).find_first_not_of(' ') == std::string::npos) { Error("Register", "Command requires an argument"); return -1; } TString cmdline = TString("register ") + TString(lfn) + TString(" ") + TString(turl); if (se) { cmdline += (TString(" ") + size + TString(" ") + TString(se)); if (guid) { cmdline += (TString(" ") + TString(guid)); } } TGridResult *result = Command(cmdline, kFALSE); if (verbose) { Stdout(); Stderr(); } if (result) { TJAlienResult *jalienresult = (TJAlienResult *) result; TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { if (gDebug > 1) Error("Register", "Register command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return kFALSE; } else { if (gDebug > 1) Info("Register", "Register command successful, registered file \"%s\"", lfn); delete result; return kTRUE; } } if (gDebug > 1) Error("Register", "Unable to register file %s", lfn); return kFALSE;*/ } //______________________________________________________________________________ TGridResult* TJAlien::ListPackages(const char* alienpackagedir) { if (!alienpackagedir) { alienpackagedir = "/alice/packages"; } TGridResult* gr = (TGridResult*) new TJAlienResult(); TGridResult* result = Ls(alienpackagedir); if (result) { Int_t i = 0; while (result->GetFileName(i)) { TString pname=result->GetFileName(i); TGridResult* version = Ls(Form("%s/%s",alienpackagedir,pname.Data())); if (version) { Int_t j=0; while (version->GetFileName(j)) { TString pversion=version->GetFileName(j); if (!pversion.Contains("post_")) { TGridResult* platform = Ls(Form("%s/%s/%s", alienpackagedir, pname.Data(), pversion.Data())); if (platform) { Int_t k = 0; TString allplatform = ""; while (platform->GetFileName(k)) { TString pplatform = platform->GetFileName(k); allplatform += pplatform; allplatform += " "; TMap* grmap = new TMap(); grmap->Add((TObject*) new TObjString("name"), (TObject*) new TObjString(pplatform.Data())); grmap->Add((TObject*) new TObjString("path"), new TObjString( Form ( "%s/%s/%s/%s" , alienpackagedir, pname.Data(), pversion.Data(), pplatform.Data()))); gr->Add(grmap); k++; } Info("ListPackages","Package: %-16s Version: %-20s Platform: [ %s ]", pname.Data(), pversion.Data(), allplatform.Data()); delete platform; } } j++; } delete version; } i++; } delete result; } return gr; } //______________________________________________________________________________ Bool_t TJAlien::Rm(const char* lfn, Option_t* options, Bool_t verbose) { if (lfn == nullptr || std::string(lfn).find_first_not_of(' ') == std::string::npos) { Error("Rm", "Command requires an argument"); return kFALSE; } TString cmdline; TString sOption(options); if (sOption.Length() > 0) cmdline = TString("rm ") + sOption + TString(" ") + TString(lfn); else cmdline = TString("rm ") + TString(lfn); TGridResult *result = Command(cmdline, kFALSE); if (verbose) { Stdout(); Stderr(); } if (result) { TJAlienResult *jalienresult = (TJAlienResult *) result; TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { if (gDebug > 1) Error("Rm", "Rm command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return kFALSE; } else { if (gDebug > 1) Info("Rm", "Rm command successful"); delete result; return kTRUE; } } if (gDebug > 1) Error("Rm", "Cannot remove %s", lfn); return kFALSE; } //______________________________________________________________________________ TJAlien::CatalogType TJAlien::Type(const char* lfn, Option_t* option, Bool_t verbose) { // returns the type of the given lfn if (lfn == nullptr || std::string(lfn).find_first_not_of(' ') == std::string::npos) { Error("Type", "Command requires an argument"); return kFailed; } TString cmdline; TString sOption(option); if (sOption.Length() > 0) { cmdline = TString("type ") + sOption + TString(" ") + TString(lfn); } else { cmdline = TString("type ") + TString(lfn); } TJAlienResult *result = (TJAlienResult*) Command(cmdline, kFALSE); if (verbose) { Stdout(); Stderr(); } if (!result) { Error("Type", "Did not receive TGridResult from query %s", cmdline.Data()); return kFailed; } //check exitcode, if command was executed successfully TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(result, errorMessage); if (exitcode != 0) { Error("Type", "Type command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return kFailed; } const char* typeStr = result->GetKey(0, "type"); if (!typeStr || strlen(typeStr) == 0) { Error("Type", "Could not get type of %s", lfn); delete result; return kFailed; } TJAlien::CatalogType type = kFailed; if (strcmp(typeStr, "file") == 0) { type = kFile; } else if (strcmp(typeStr, "directory") == 0) { type = kDirectory; } else if (strcmp(typeStr, "collection") == 0) { type = kCollection; } else Error("Type", "Unknown type %s", typeStr); delete result; return type; } //______________________________________________________________________________ TGridJob *TJAlien::Submit(const char *jdl) { // Submit a command to JAliEn. Returns 0 in case of error. if (!jdl) return 0; TString command = TString("submit "); command += jdl; if (gDebug > 1) Info("TJAlien", "command: %s", command.Data()); TGridResult* result = Command(command, kFALSE, kOUTPUT); TJAlienResult* jalienResult = dynamic_cast (result); TList* list = dynamic_cast (jalienResult); if (!list) { if (result) delete result; return 0; } //check exitcode, if command was executed successfully if (jalienResult) { TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienResult, errorMessage); if (exitcode != 0) { Error("Submit", "Submit command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return 0; } } jalienResult->DumpResult(); TString jobID = "0"; TIterator* iter = list->MakeIterator(); TObject* object = 0; while ((object = iter->Next()) != 0) { TMap* map = dynamic_cast(object); TObject* jobIDObject = map->GetValue("jobId"); TObjString* jobIDStr = dynamic_cast (jobIDObject); if (jobIDStr) jobID = jobIDStr->GetString(); } delete iter; delete result; if (jobID == "0") { Error("Submit", "Error submitting job"); return 0; } Info("Submit", "Your job was submitted with the ID = %s", jobID.Data()); return dynamic_cast (new TJAlienJob(jobID)); } //______________________________________________________________________________ TGridJDL *TJAlien::GetJDLGenerator() { return new TJAlienJDL(); } //______________________________________________________________________________ const char *TJAlien::GetHomeDirectory() { if (!IsConnected()) Connect(); return fHome.Data(); } // TODO not implemented in java, TEST!!!! //______________________________________________________________________________ Bool_t TJAlien::ResubmitById(TString jobid) { // Resubmit a specific job. TString cmdline = TString("resubmit ") + jobid; TGridResult *result = Command(cmdline, kFALSE); if (result) { TJAlienResult *jalienresult = (TJAlienResult *) result; TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { Error("ResubmitById", "ResubmitByIt command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return kFALSE; } else { Info("ResubmitById", "ResubmitById command successful, submited job \"%s\"", jobid.Data()); delete result; return kTRUE; } } return kFALSE; } // TODO not implemented in java, TEST!!!! //______________________________________________________________________________ Bool_t TJAlien::KillById(TString jobid) { // Kill a specific job. TString cmdline = TString("kill ") + jobid; TGridResult *result = Command(cmdline, kFALSE); if (result) { TJAlienResult *jalienresult = (TJAlienResult *) result; TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { Error("KillById", "KillById command failed with error message \"%s\"", errorMessage->GetString().Data()); delete result; return kFALSE; } else { Info("KillById", "KillById command successful, killed job \"%s\"", jobid.Data()); delete result; return kTRUE; } } return kFALSE; } //______________________________________________________________________________ TGridJobStatusList *TJAlien::Ps(const char* options, Bool_t verbose) { UNUSED(verbose); TString cmdline("ps"); if (options != nullptr && std::string(options).find_first_not_of(' ') != std::string::npos) { TString sOptions(options); cmdline += TString(" ") + sOptions; } TJAlienResult *jalienresult = (TJAlienResult*) Command(cmdline, kFALSE); Stdout(); Stderr(); if (jalienresult) { TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { Error("Ps", "%s", errorMessage->GetString().Data()); delete jalienresult; return nullptr; } } else { Error("Ps", "Ps: error while running command, no return result"); return nullptr; } //jalienresult->DumpResult(); TList *list = dynamic_cast (jalienresult); if (!list) { if (jalienresult) delete jalienresult; Error("Ps", "Ps: error while running command, no empty result returned"); return nullptr; } TJAlienJobStatusList *joblist = new TJAlienJobStatusList(); TIterator *it = list->MakeIterator(); TObject *object = it->Next(); while (object != 0) { TMap *status = dynamic_cast (object); TJAlienJobStatus *jobstatus = new TJAlienJobStatus(status); //if (verbose) jobstatus->Print(""); joblist->Add((TGridJobStatus*)jobstatus); object = it->Next(); } delete jalienresult; return joblist; } //______________________________________________________________________________ const char *TJAlien::Pwd(Bool_t verbose) { if (!IsConnected()) Connect(); return fPwd.Data(); }; //______________________________________________________________________________ TGridResult* TJAlien::GetCollection(const char* lfn, Option_t* option, Bool_t verbose) { if (lfn == nullptr || std::string(lfn).find_first_not_of(' ') == std::string::npos) lfn = GetHomeDirectory(); TString cmdline; TString sOption(option); if (sOption != 0 && sOption.Length() > 0) { cmdline = TString("listFilesFromCollection ") + sOption + TString(" ") + TString(lfn); } else { cmdline = TString("listFilesFromCollection ") + TString(lfn); } TGridResult* gridResult = Command(cmdline, kFALSE); if (verbose) { Stdout(); Stderr(); } return gridResult; } //______________________________________________________________________________ TGridCollection *TJAlien::OpenCollection(const char *collectionfile, UInt_t maxentries) { // Factory function for a TJAlienCollection based on an XML file. TString path(collectionfile); if (path.BeginsWith("alien://", TString::kIgnoreCase)) { TJAlien* jalien = dynamic_cast (gGrid); if (!jalien) { Error("OpenCollection", "Trying to read a collection, but gGrid is not initialized with JAliEn"); return 0; } TString lfn = path(strlen("alien://"), path.Length()); if (jalien->Type(lfn) == kCollection) { // it is a collection TGridResult* gridResult = jalien->GetCollection(lfn, 0, kFALSE); if (!gridResult) { Error("OpenCollection", "Could not retrieve collection %s from the catalog", collectionfile); return 0; } //check exitcode, if command was executed successfully TJAlienResult *jalienresult = (TJAlienResult *) gridResult; TObjString *errorMessage = 0; Int_t exitcode = GetExitCode(jalienresult, errorMessage); if (exitcode != 0) { Error("OpenCollection", "OpenCollection command failed with error message \"%s\"", errorMessage->GetString().Data()); delete gridResult; return 0; } return TJAlienCollection::OpenJAliEnCollection(gridResult); } } return TJAlienCollection::Open(collectionfile, maxentries); } //______________________________________________________________________________ TGridCollection *TJAlien::OpenCollectionQuery(TGridResult *queryresult, Bool_t nogrouping) { // Factory function fo a TJAlienCollection based on a gGrid Query. return (TGridCollection*)TJAlienCollection::OpenQuery(queryresult, nogrouping); } //______________________________________________________________________________ TGridResult *TJAlien::OpenDataset(const char *lfn, const char *options) { UNUSED(lfn); UNUSED(options); (dynamic_cast (gGrid))->NotImplemented(__func__, __FILE__, __LINE__); return nullptr; } //______________________________________________________________________________ TMap *TJAlien::GetColumn(UInt_t stream, UInt_t column) { UNUSED(stream); UNUSED(column); (dynamic_cast (gGrid))->NotImplemented(__func__, __FILE__, __LINE__); return nullptr; } //______________________________________________________________________________ const char *TJAlien::GetStreamFieldValue(UInt_t stream, UInt_t column, UInt_t row) { UNUSED(stream); UNUSED(column); UNUSED(row); (dynamic_cast (gGrid))->NotImplemented(__func__, __FILE__, __LINE__); return nullptr; } //______________________________________________________________________________ const char *TJAlien::GetStreamFieldKey(UInt_t stream, UInt_t column, UInt_t row) { UNUSED(stream); UNUSED(column); UNUSED(row); (dynamic_cast (gGrid))->NotImplemented(__func__, __FILE__, __LINE__); return nullptr; } //______________________________________________________________________________ UInt_t TJAlien::GetNColumns(UInt_t stream) { UNUSED(stream); (dynamic_cast (gGrid))->NotImplemented(__func__, __FILE__, __LINE__); return -1; } //______________________________________________________________________________ TGridResult *TJAlien::Query(const char *path, const char *pattern, const char *conditions, const char *options) { // this command should create collection using 'find -c' // in TJAlienResult should be path to this created collection // BUT change of java part is needed, this does not work now TODO TString cmdline = TString("find"); TString sPath(path); TString sPattern(pattern); TString sConditions(conditions); TString sOptions(options); if (sOptions.Length() > 0) cmdline += TString(" ") + sOptions; if (sPath.Length() > 0) cmdline += TString(" ") + sPath; if (sPattern.Length() > 0) cmdline += TString(" ") + sPattern; if (sConditions.Length() > 0) cmdline += TString(" ") + sConditions; return Command(cmdline); } //______________________________________________________________________________ Int_t TJAlien::GetExitCode(TJAlienResult *result, TObjString* &message) { // Extracting the exit code and error message from a TJAlien result if (!result) { Error("GetExitCode", "Could not retrieve the exit code, the result is nullptr"); return -1; } TObjString *key = new TObjString(); key->SetString("exitcode"); TObjString *ecStr = result->GetMetaData(key); Int_t exitcode = 0; if (ecStr != nullptr) exitcode = ecStr->GetString().Atoi(); if (exitcode != 0) { key->SetString("error"); //message->SetString(result->GetMetaData(key)->GetString().Data()); message = result->GetMetaData(key); } delete key; return exitcode; } //______________________________________________________________________________ const char* TJAlien::Whoami() { if (!IsConnected()) Connect(); return fUser.Data(); }; //______________________________________________________________________________ TGridResult* TJAlien::SetSite(const char *site) { TString cmdline = TString("setSite"); if (site != nullptr && std::string(site).find_first_not_of(' ') != std::string::npos) cmdline += TString(" ") + site; return Command(cmdline); } //______________________________________________________________________________ void TJAlien::NotImplemented(const char *func, const char *file, int line) { Error("TJAlien", "You are trying to call:"); Error("TJAlien", " %s", func); Error("TJAlien", " in %s:%d", file, line); Error("TJAlien", "that is NOT IMPLEMENTED."); Error("TJAlien", "If you need this method please contact JAliEn support "); }