00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "TAlienFile.h"
00032 #include "TAlienResult.h"
00033 #include "TAlien.h"
00034 #include "TROOT.h"
00035 #include "TObjString.h"
00036 #include "TMap.h"
00037 #include "TObjArray.h"
00038 #include "TString.h"
00039 #include "Rtypes.h"
00040 #include "TSystem.h"
00041 #include "TVirtualMonitoring.h"
00042 #include "TVirtualMutex.h"
00043 #include "TProcessUUID.h"
00044 #include "TUrl.h"
00045 #include "TError.h"
00046 #include <cstdlib>
00047
00048 ClassImp(TAlienFile)
00049
00050 #define MAX_FILE_IMAGES 16
00051
00052
00053 TAlienFile::TAlienFile(const char *purl, Option_t *option,
00054 const char *ftitle, Int_t compress,
00055 Bool_t parallelopen, const char *lurl,
00056 const char *authz) :
00057 TXNetFile(purl, option, ftitle, compress, 0, parallelopen, lurl)
00058 {
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 TUrl logicalurl(lurl);
00088 fLfn = logicalurl.GetFile();
00089 fAuthz = authz;
00090 }
00091
00092
00093 TAlienFile *TAlienFile::Open(const char *url, Option_t *option,
00094 const char *ftitle, Int_t compress,
00095 Bool_t parallelopen)
00096 {
00097
00098
00099
00100 if (!gGrid) {
00101 ::Error("TAlienFileAccess", "No GRID connection available!");
00102 return 0;
00103 }
00104 TUrl lUrl(url);
00105
00106
00107 if (gMonitoringWriter)
00108 gMonitoringWriter->SendFileOpenProgress(0, 0, "alienopen", kFALSE);
00109
00110 TString name(TString("alien://") + TString(lUrl.GetFile()));
00111 TString fAName = name;
00112 TString fAOption = option;
00113 TUrl fAUrl;
00114 Bool_t fAWritable;
00115 fAWritable = kFALSE;
00116 TString authz;
00117
00118
00119
00120 TString stmp;
00121 Bool_t create;
00122 Bool_t recreate;
00123 Bool_t update;
00124 Bool_t read;
00125
00126 TUrl purl(url);
00127
00128
00129 TString storageelement;
00130 storageelement = "";
00131 TString file = purl.GetFile();
00132
00133 Bool_t publicaccess = kFALSE;
00134 storageelement = gSystem->Getenv("alien_CLOSE_SE");
00135
00136
00137 TString urloptions = purl.GetOptions();
00138 TObjArray *objOptions = urloptions.Tokenize("&");
00139 for (Int_t n = 0; n < objOptions->GetEntries(); n++) {
00140 TString loption = ((TObjString *) objOptions->At(n))->GetName();
00141 TObjArray *objTags = loption.Tokenize("=");
00142 if (objTags->GetEntries() == 2) {
00143 TString key = ((TObjString *) objTags->At(0))->GetName();
00144 TString value = ((TObjString *) objTags->At(1))->GetName();
00145 if (!key.CompareTo("se", TString::kIgnoreCase)) {
00146 storageelement = value;
00147 }
00148 if (!key.CompareTo("publicaccess")) {
00149 if (atoi(value.Data()))
00150 publicaccess = kTRUE;
00151 }
00152 }
00153 delete objTags;
00154 }
00155 delete objOptions;
00156
00157 fAOption = option;
00158 fAOption.ToUpper();
00159
00160 TObjString *urlStr = 0;
00161 TObjString *authzStr = 0;
00162 TObjString *seStr = 0;
00163
00164 TString command;
00165 TString repcommand;
00166 TIterator *iter = 0;
00167 TObject *object = 0;
00168
00169 TGridResult *result;
00170 TAlienResult *alienResult;
00171 TList *list;
00172
00173 TString stringurl;
00174 TString anchor;
00175 TObjArray *tokens;
00176 anchor = "";
00177
00178 TString newurl;
00179 if (fAOption == "NEW")
00180 fAOption = "CREATE";
00181
00182 create = (fAOption == "CREATE") ? kTRUE : kFALSE;
00183 recreate = (fAOption == "RECREATE") ? kTRUE : kFALSE;
00184 update = (fAOption == "UPDATE") ? kTRUE : kFALSE;
00185 read = (fAOption == "READ") ? kTRUE : kFALSE;
00186
00187 if (!create && !recreate && !update && !read) {
00188 read = kTRUE;
00189 fAOption = "READ";
00190 }
00191
00192 if (create || recreate || update) {
00193 fAWritable = kTRUE;
00194 }
00195
00196 if (recreate) {
00197 fAOption = "RECREATE";
00198 create = kTRUE;
00199 }
00200
00201
00202
00203 if (!gGrid) {
00204
00205 ::Error("TAlienFile::Open", "no active GRID connection found");
00206 fAUrl = "";
00207
00208
00209 if (gMonitoringWriter)
00210 gMonitoringWriter->SendFileOpenProgress(0, 0, 0, kFALSE);
00211
00212 return 0;
00213 } else {
00214 if ((strcmp(gGrid->GetGrid(), "alien"))) {
00215 ::Error("TAlienFile::Open", "you don't have an active <alien> grid!");
00216 fAUrl = "";
00217
00218
00219 if (gMonitoringWriter)
00220 gMonitoringWriter->SendFileOpenProgress(0, 0, 0, kFALSE);
00221
00222 return 0;
00223 }
00224 }
00225
00226
00227
00228
00229 if (read) {
00230
00231 if (publicaccess)
00232 command = TString("access -p read ");
00233 else
00234 command = TString("access read ");
00235 }
00236
00237 if (create) {
00238 command = TString("access write-once ");
00239 }
00240
00241 if (recreate) {
00242 command = TString("access write-version ");
00243 }
00244
00245 if (update) {
00246 command = TString("access write-version ");
00247 }
00248
00249 command += file;
00250
00251 if (fAWritable) {
00252
00253 command += " ";
00254 command += storageelement;
00255 }
00256
00257 TString fALfn = file;
00258
00259 int imagenr = 0;
00260
00261 do {
00262 imagenr++;
00263 repcommand = command;
00264 if (!fAWritable) {
00265
00266 if (storageelement != "") {
00267 repcommand += " ";
00268 repcommand += storageelement;
00269 } else {
00270 repcommand += " ";
00271 repcommand += "unknown";
00272 }
00273 repcommand += " 0 ";
00274 repcommand += imagenr;
00275 }
00276
00277 result = gGrid->Command(repcommand.Data(), kFALSE, TAlien::kOUTPUT);
00278 alienResult = dynamic_cast < TAlienResult * >(result);
00279 list = dynamic_cast < TList * >(alienResult);
00280 if (!list) {
00281
00282 if (seStr)
00283 ::Error("TAlienFile::Open",
00284 "cannot get the access envelope for %s and image %u in SE <%s>",
00285 purl.GetUrl(), imagenr, seStr->GetName());
00286 else
00287 ::Error("TAlienFile::Open",
00288 "cannot get the access envelope for %s and image %u",
00289 purl.GetUrl(), imagenr);
00290 fAUrl = "";
00291 if (result) {
00292 delete result;
00293 }
00294
00295
00296 if (gMonitoringWriter)
00297 gMonitoringWriter->SendFileOpenProgress(0, 0, 0, kFALSE);
00298
00299 return 0;
00300 }
00301
00302 iter = list->MakeIterator();
00303 object = 0;
00304
00305 Bool_t imageeof = kFALSE;
00306
00307 while ((object = iter->Next()) != 0) {
00308 TMap *map = dynamic_cast < TMap * >(object);
00309
00310 TObject *urlObject = map->GetValue("url");
00311 urlStr = dynamic_cast < TObjString * >(urlObject);
00312
00313 TObject *authzObject = map->GetValue("envelope");
00314 authzStr = dynamic_cast < TObjString * >(authzObject);
00315
00316 TObject *seObject = map->GetValue("se");
00317 seStr = dynamic_cast < TObjString * >(seObject);
00318
00319 if (map->GetValue("eof")) {
00320 imageeof = kTRUE;
00321
00322 }
00323 break;
00324 }
00325
00326 if ((!urlStr) || (!authzStr)) {
00327 if (fAWritable) {
00328 ::Error("TAlienFile::Open",
00329 "didn't get the authorization to write %s",
00330 purl.GetUrl());
00331 } else {
00332 if (!imageeof) {
00333 ::Error("TAlienFile::Open",
00334 "didn't get the authorization to read %s from location %u",
00335 purl.GetUrl(), imagenr);
00336 }
00337 }
00338 if (!imageeof) {
00339 ::Info("TAlienFile::Open",
00340 "Command::Stdout !!!");
00341 gGrid->Stdout();
00342 ::Info("TAlienFile::Open",
00343 "Command::Stderr !!!");
00344 gGrid->Stderr();
00345 ::Info("TAlienFile::Open",
00346 "End of Output !!!");
00347 }
00348 delete iter;
00349 delete result;
00350 fAUrl = "";
00351 if (!imageeof) {
00352 continue;
00353 } else {
00354
00355 ::Error("TAlienFile::Open",
00356 "No more images to try - giving up");
00357
00358
00359 if (gMonitoringWriter)
00360 gMonitoringWriter->SendFileOpenProgress(0, 0, 0, kFALSE);
00361
00362 return 0;
00363 }
00364 }
00365
00366 delete iter;
00367
00368 authz = authzStr->GetName();
00369 stringurl = urlStr->GetName();
00370
00371 tokens = stringurl.Tokenize("#");
00372
00373 if (tokens->GetEntries() == 2) {
00374 anchor = ((TObjString *) tokens->At(1))->GetName();
00375 urlStr->SetString(((TObjString *) tokens->At(0))->GetName());
00376 }
00377
00378 if (tokens) {
00379 delete tokens;
00380 }
00381
00382 newurl = urlStr->GetName();
00383 stmp = purl.GetAnchor();
00384 newurl += TString("?&authz=");
00385 newurl += authzStr->GetName();
00386
00387 if (!fAWritable) {
00388 if (seStr)
00389 ::Info("TAlienFile::Open", "Accessing image %u of %s in SE <%s>",
00390 imagenr, purl.GetUrl(), seStr->GetName());
00391 else
00392 ::Info("TAlienFile::Open", "Accessing image %u of %s", imagenr, purl.GetUrl());
00393 }
00394
00395
00396
00397
00398
00399 if (stmp != "") {
00400 newurl += "#";
00401 newurl += purl.GetAnchor();
00402 TString lUrlfile = lUrl.GetFile();
00403 TString lUrloption;
00404 lUrloption = "zip=";
00405 lUrloption += purl.GetAnchor();
00406 lUrloption += "&mkpath=1";
00407 lUrl.SetFile(lUrlfile);
00408 lUrl.SetOptions(lUrloption);
00409 } else {
00410 if (anchor.Length()) {
00411 newurl += "#";
00412 newurl += anchor;
00413 TString lUrlfile = lUrl.GetFile();
00414 TString lUrloption;
00415 lUrloption = "zip=";
00416 lUrloption += anchor;
00417 lUrloption += "&mkpath=1";
00418 lUrl.SetFile(lUrlfile);
00419
00420 lUrl.SetOptions(lUrloption);
00421 } else {
00422 TString loption;
00423 loption = lUrl.GetOptions();
00424 if (loption.Length()) {
00425 loption += "&mkpath=1";
00426 lUrl.SetOptions(loption.Data());
00427 } else {
00428 lUrl.SetOptions("mkpath=1");
00429 }
00430 }
00431 }
00432
00433 fAUrl = TUrl(newurl);
00434
00435
00436 TString oldopt;
00437 TString newopt;
00438
00439 if (TString(fAUrl.GetUrl()) == "") {
00440
00441
00442
00443 if (gMonitoringWriter)
00444 gMonitoringWriter->SendFileOpenProgress(0, 0, 0, kFALSE);
00445
00446 return 0;
00447 }
00448
00449 TUrl nUrl = fAUrl;
00450 TUrl oUrl(url);
00451
00452 oldopt = oUrl.GetOptions();
00453 newopt = nUrl.GetOptions();
00454
00455
00456 if (oldopt.Length()) {
00457 nUrl.SetOptions(newopt + TString("&") + oldopt);
00458 } else {
00459 nUrl.SetOptions(newopt);
00460 }
00461
00462 fAUrl = nUrl;
00463 delete result;
00464 if (gDebug > 1)
00465 ::Info("TAlienFile","Opening AUrl <%s> lUrl <%s>",fAUrl.GetUrl(),lUrl.GetUrl());
00466 TAlienFile *alienfile =
00467 new TAlienFile(fAUrl.GetUrl(), fAOption, ftitle, compress,
00468 parallelopen, lUrl.GetUrl(), authz);
00469 if (alienfile->IsZombie()) {
00470 delete alienfile;
00471 if (fAWritable) {
00472
00473 break;
00474 }
00475 continue;
00476 } else {
00477 return alienfile;
00478 }
00479 } while (imagenr < MAX_FILE_IMAGES);
00480
00481 if (!fAWritable) {
00482 ::Error("TAlienFile::Open",
00483 "Couldn't open any of the file images of %s", lUrl.GetUrl());
00484 }
00485
00486
00487 if (gMonitoringWriter)
00488 gMonitoringWriter->SendFileOpenProgress(0, 0, 0, kFALSE);
00489
00490 return 0;
00491 }
00492
00493
00494 TAlienFile::~TAlienFile()
00495 {
00496
00497
00498 if (IsOpen()) {
00499 Close();
00500 }
00501 if (gDebug)
00502 Info("~TAlienFile", "dtor called for %s", GetName());
00503 }
00504
00505
00506 void TAlienFile::Close(Option_t * option)
00507 {
00508
00509
00510 if (!IsOpen()) return;
00511
00512
00513
00514 TXNetFile::Close(option);
00515
00516 if (fOption == "READ")
00517 return;
00518
00519
00520 gSystem->Setenv("GCLIENT_EXTRA_ARG", fAuthz.Data());
00521
00522
00523 TString command("commit ");
00524
00525 Long64_t siz = GetSize();
00526 if (siz <= 0)
00527 Error("Close", "the reported size of the written file is <= 0");
00528
00529 command += siz;
00530 command += " ";
00531 command += fLfn;
00532
00533 TGridResult *result = gGrid->Command(command, kFALSE, TAlien::kOUTPUT);
00534 TAlienResult *alienResult = dynamic_cast < TAlienResult * >(result);
00535 TList *list = dynamic_cast < TList * >(alienResult);
00536 if (!list) {
00537 if (result) {
00538 delete result;
00539 }
00540 Error("Close", "cannot commit envelope for %s", fLfn.Data());
00541 gSystem->Unlink(fLfn);
00542 }
00543 TIterator *iter = list->MakeIterator();
00544 TObject *object = 0;
00545 if (fWritable) {
00546 while ((object = iter->Next()) != 0) {
00547 TMap *map = dynamic_cast < TMap * >(object);
00548 TObject *commitObject = map->GetValue(fLfn.Data());
00549 if (commitObject) {
00550 TObjString *commitStr =
00551 dynamic_cast < TObjString * >(commitObject);
00552 if (!(strcmp(commitStr->GetName(), "1"))) {
00553
00554 break;
00555 }
00556 }
00557
00558 Error("Close", "cannot register %s!", fLfn.Data());
00559 gSystem->Unlink(fLfn);
00560
00561 break;
00562 }
00563 delete iter;
00564 delete result;
00565 }
00566
00567 gSystem->Unsetenv("GCLIENT_EXTRA_ARG");
00568
00569 }
00570
00571
00572 TString TAlienFile::SUrl(const char *lfn)
00573 {
00574
00575
00576 TString command;
00577 TString surl;
00578
00579 if (!lfn) {
00580 return surl;
00581 }
00582
00583 TUrl lurl(lfn);
00584 command = "access -p read ";
00585 command += lurl.GetFile();
00586
00587 TGridResult* result;
00588
00589 if (!gGrid) {
00590 ::Error("TAlienFile::SUrl","no grid connection");
00591 return surl;
00592 }
00593
00594 result = gGrid->Command(command.Data(), kFALSE, TAlien::kOUTPUT);
00595 if (!result) {
00596 ::Error("TAlienFile::SUrl","couldn't get access URL for alien file %s", lfn);
00597 return surl;
00598 }
00599
00600 TIterator *iter = result->MakeIterator();
00601 TObject *object=0;
00602 TObjString *urlStr=0;
00603
00604 object = iter->Next();
00605 if (object) {
00606 TMap *map = dynamic_cast < TMap * >(object);
00607 TObject *urlObject = map->GetValue("url");
00608 urlStr = dynamic_cast < TObjString * >(urlObject);
00609
00610 if (urlStr) {
00611 surl = urlStr->GetName();
00612 delete object;
00613 return surl;
00614 }
00615 }
00616
00617 ::Error("TAlienFile::SUrl","couldn't get surl for alien file %s", lfn);
00618 return surl;
00619 }