Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : /////////////////////////////////////////////////////////////////////////////////////////////////
17 : // //
18 : // AliCDBGrid //
19 : // access class to a DataBase in an AliEn storage //
20 : // //
21 : /////////////////////////////////////////////////////////////////////////////////////////////////
22 :
23 : #include <cstdlib>
24 : #include <TGrid.h>
25 : #include <TGridResult.h>
26 : #include <TFile.h>
27 : #include <TKey.h>
28 : #include <TROOT.h>
29 : #include <TList.h>
30 : #include <TObjArray.h>
31 : #include <TObjString.h>
32 : #include <TMath.h>
33 : #include <TRegexp.h>
34 :
35 : #include "AliLog.h"
36 : #include "AliCDBEntry.h"
37 : #include "AliCDBGrid.h"
38 : #include "AliCDBManager.h"
39 :
40 :
41 128 : ClassImp(AliCDBGrid)
42 :
43 : //_____________________________________________________________________________
44 : AliCDBGrid::AliCDBGrid(const char *gridUrl, const char *user, const char *dbFolder,
45 : const char *se, const char* cacheFolder, Bool_t operateDisconnected,
46 : Long64_t cacheSize, Long_t cleanupInterval) :
47 0 : AliCDBStorage(),
48 0 : fGridUrl(gridUrl),
49 0 : fUser(user),
50 0 : fDBFolder(dbFolder),
51 0 : fSE(se),
52 0 : fMirrorSEs(""),
53 0 : fCacheFolder(cacheFolder),
54 0 : fOperateDisconnected(operateDisconnected),
55 0 : fCacheSize(cacheSize),
56 0 : fCleanupInterval(cleanupInterval)
57 0 : {
58 : // constructor //
59 :
60 : // if the same Grid is alreay active, skip connection
61 0 : if (!gGrid || fGridUrl != gGrid->GridUrl()
62 0 : || (( fUser != "" ) && ( fUser != gGrid->GetUser() )) ) {
63 : // connection to the Grid
64 0 : AliInfo("Connection to the Grid...");
65 0 : if(gGrid){
66 0 : AliInfo(Form("gGrid = %p; fGridUrl = %s; gGrid->GridUrl() = %s",gGrid,fGridUrl.Data(), gGrid->GridUrl()));
67 0 : AliInfo(Form("fUser = %s; gGrid->GetUser() = %s",fUser.Data(), gGrid->GetUser()));
68 : }
69 0 : TGrid::Connect(fGridUrl.Data(),fUser.Data());
70 : }
71 :
72 0 : if(!gGrid) {
73 0 : AliError("Connection failed!");
74 : return;
75 : }
76 :
77 0 : TString initDir(gGrid->Pwd(0));
78 0 : if (fDBFolder[0] != '/') {
79 0 : fDBFolder.Prepend(initDir);
80 : }
81 :
82 : // check DBFolder: trying to cd to DBFolder; if it does not exist, create it
83 0 : if(!gGrid->Cd(fDBFolder.Data(),0)){
84 0 : AliDebug(2,Form("Creating new folder <%s> ...",fDBFolder.Data()));
85 0 : TGridResult* res = gGrid->Command(Form("mkdir -p %s",fDBFolder.Data()));
86 0 : TString result = res->GetKey(0,"__result__");
87 0 : if(result == "0"){
88 0 : AliFatal(Form("Cannot create folder <%s> !",fDBFolder.Data()));
89 0 : return;
90 : }
91 0 : } else {
92 0 : AliDebug(2,Form("Folder <%s> found",fDBFolder.Data()));
93 : }
94 :
95 : // removes any '/' at the end of path, then append one '/'
96 0 : while(fDBFolder.EndsWith("/")) fDBFolder.Remove(fDBFolder.Last('/'));
97 0 : fDBFolder+="/";
98 :
99 0 : fType="alien";
100 0 : fBaseFolder = fDBFolder;
101 :
102 : // Setting the cache
103 :
104 : // Check if local cache folder is already defined
105 0 : TString origCache(TFile::GetCacheFileDir());
106 0 : if(fCacheFolder.Length() > 0) {
107 0 : if(origCache.Length() == 0) {
108 0 : AliInfo(Form("Setting local cache to: %s", fCacheFolder.Data()));
109 0 : } else if(fCacheFolder != origCache) {
110 0 : AliWarning(Form("Local cache folder was already defined, changing it to: %s",
111 : fCacheFolder.Data()));
112 : }
113 :
114 : // default settings are: operateDisconnected=kTRUE, forceCacheread = kFALSE
115 0 : if(!TFile::SetCacheFileDir(fCacheFolder.Data(), fOperateDisconnected)) {
116 0 : AliError(Form("Could not set cache folder %s !", fCacheFolder.Data()));
117 0 : fCacheFolder = "";
118 : } else {
119 : // reset fCacheFolder because the function may have
120 : // slightly changed the folder name (e.g. '/' added)
121 0 : fCacheFolder = TFile::GetCacheFileDir();
122 : }
123 :
124 : // default settings are: cacheSize=1GB, cleanupInterval = 0
125 0 : if(!TFile::ShrinkCacheFileDir(fCacheSize, fCleanupInterval)) {
126 0 : AliError(Form("Could not set following values "
127 : "to ShrinkCacheFileDir: cacheSize = %lld, cleanupInterval = %ld !",
128 : fCacheSize, fCleanupInterval));
129 : }
130 : }
131 :
132 : // return to the initial directory
133 0 : gGrid->Cd(initDir.Data(),0);
134 :
135 0 : fNretry = 3; // default
136 0 : fInitRetrySeconds = 5; // default
137 0 : }
138 :
139 : //_____________________________________________________________________________
140 0 : AliCDBGrid::~AliCDBGrid() {
141 : // destructor
142 0 : delete gGrid; gGrid=0;
143 :
144 0 : }
145 :
146 : //_____________________________________________________________________________
147 : Bool_t AliCDBGrid::FilenameToId(TString& filename, AliCDBId& id) {
148 : // build AliCDBId from full path filename (fDBFolder/path/Run#x_#y_v#z_s0.root)
149 :
150 0 : if(filename.Contains(fDBFolder)){
151 0 : filename = filename(fDBFolder.Length(),filename.Length()-fDBFolder.Length());
152 0 : }
153 :
154 0 : TString idPath = filename(0,filename.Last('/'));
155 0 : id.SetPath(idPath);
156 0 : if(!id.IsValid()) return kFALSE;
157 :
158 0 : filename=filename(idPath.Length()+1,filename.Length()-idPath.Length());
159 :
160 0 : Ssiz_t mSize;
161 : // valid filename: Run#firstRun_#lastRun_v#version_s0.root
162 0 : TRegexp keyPattern("^Run[0-9]+_[0-9]+_v[0-9]+_s0.root$");
163 0 : keyPattern.Index(filename, &mSize);
164 0 : if (!mSize) {
165 :
166 : // TODO backward compatibility ... maybe remove later!
167 0 : Ssiz_t oldmSize;
168 0 : TRegexp oldKeyPattern("^Run[0-9]+_[0-9]+_v[0-9]+.root$");
169 0 : oldKeyPattern.Index(filename, &oldmSize);
170 0 : if(!oldmSize) {
171 0 : AliDebug(2,Form("Bad filename <%s>.", filename.Data()));
172 0 : return kFALSE;
173 : } else {
174 0 : AliDebug(2,Form("Old filename format <%s>.", filename.Data()));
175 0 : id.SetSubVersion(-11); // TODO trick to ensure backward compatibility
176 : }
177 :
178 0 : } else {
179 0 : id.SetSubVersion(-1); // TODO trick to ensure backward compatibility
180 : }
181 :
182 0 : filename.Resize(filename.Length() - sizeof(".root") + 1);
183 :
184 0 : TObjArray* strArray = (TObjArray*) filename.Tokenize("_");
185 :
186 0 : TString firstRunString(((TObjString*) strArray->At(0))->GetString());
187 0 : id.SetFirstRun(atoi(firstRunString.Data() + 3));
188 0 : id.SetLastRun(atoi(((TObjString*) strArray->At(1))->GetString()));
189 :
190 0 : TString verString(((TObjString*) strArray->At(2))->GetString());
191 0 : id.SetVersion(atoi(verString.Data() + 1));
192 :
193 0 : delete strArray;
194 :
195 : return kTRUE;
196 0 : }
197 :
198 : //_____________________________________________________________________________
199 : Bool_t AliCDBGrid::IdToFilename(const AliCDBId& id, TString& filename) const {
200 : // build file name from AliCDBId (path, run range, version) and fDBFolder
201 :
202 0 : if (!id.GetAliCDBRunRange().IsValid()) {
203 0 : AliDebug(2,Form("Invalid run range <%d, %d>.",
204 : id.GetFirstRun(), id.GetLastRun()));
205 0 : return kFALSE;
206 : }
207 :
208 0 : if (id.GetVersion() < 0) {
209 0 : AliDebug(2,Form("Invalid version <%d>.", id.GetVersion()));
210 0 : return kFALSE;
211 : }
212 :
213 0 : filename = Form("Run%d_%d_v%d",
214 0 : id.GetFirstRun(),
215 0 : id.GetLastRun(),
216 0 : id.GetVersion());
217 :
218 0 : if (id.GetSubVersion() != -11) filename += "_s0"; // TODO to ensure backward compatibility
219 0 : filename += ".root";
220 :
221 0 : filename.Prepend(fDBFolder + id.GetPath() + '/');
222 :
223 0 : return kTRUE;
224 0 : }
225 :
226 : //_____________________________________________________________________________
227 : void AliCDBGrid::SetRetry(Int_t nretry, Int_t initsec) {
228 :
229 : // Function to set the exponential retry for putting entries in the OCDB
230 :
231 0 : AliWarning("WARNING!!! You are changing the exponential retry times and delay: this function should be used by experts!");
232 0 : fNretry = nretry;
233 0 : fInitRetrySeconds = initsec;
234 0 : AliDebug(2,Form("fNretry = %d, fInitRetrySeconds = %d", fNretry, fInitRetrySeconds));
235 0 : }
236 :
237 :
238 : //_____________________________________________________________________________
239 : Bool_t AliCDBGrid::PrepareId(AliCDBId& id) {
240 : // prepare id (version) of the object that will be stored (called by PutEntry)
241 :
242 0 : TString initDir(gGrid->Pwd(0));
243 :
244 0 : TString dirName(fDBFolder);
245 :
246 : Bool_t dirExist=kFALSE;
247 :
248 :
249 :
250 : // go to the path; if directory does not exist, create it
251 0 : for(int i=0;i<3;i++){
252 : //TString cmd("find -d ");
253 : //cmd += Form("%s ",dirName);
254 : //cmd +=
255 : //gGrid->Command(cmd.Data());
256 0 : dirName+=Form("%s/",id.GetPathLevel(i).Data());
257 0 : dirExist=gGrid->Cd(dirName,0);
258 0 : if (!dirExist) {
259 0 : AliDebug(2,Form("Creating new folder <%s> ...",dirName.Data()));
260 0 : if(!gGrid->Mkdir(dirName,"",0)){
261 0 : AliError(Form("Cannot create directory <%s> !",dirName.Data()));
262 0 : gGrid->Cd(initDir.Data());
263 0 : return kFALSE;
264 : }
265 :
266 : // if folders are new add tags to them
267 0 : if(i == 1) {
268 : // TODO Currently disabled
269 : // add short lived tag!
270 : // AliInfo("Tagging level 1 folder with \"ShortLived\" tag");
271 : // if(!AddTag(dirName,"ShortLived_try")){
272 : // AliError(Form("Could not tag folder %s !", dirName.Data()));
273 : // if(!gGrid->Rmdir(dirName.Data())){
274 : // AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
275 : // }
276 : // return 0;
277 : //}
278 :
279 0 : } else if(i == 2) {
280 0 : AliDebug(2,"Tagging level 2 folder with \"CDB\" and \"CDB_MD\" tag");
281 0 : if(!AddTag(dirName,"CDB")){
282 0 : AliError(Form("Could not tag folder %s !", dirName.Data()));
283 0 : if(!gGrid->Rmdir(dirName.Data())){
284 0 : AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
285 : }
286 0 : return 0;
287 : }
288 0 : if(!AddTag(dirName,"CDB_MD")){
289 0 : AliError(Form("Could not tag folder %s !", dirName.Data()));
290 0 : if(!gGrid->Rmdir(dirName.Data())){
291 0 : AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
292 : }
293 0 : return 0;
294 : }
295 :
296 : // TODO Currently disabled
297 : // add short lived tag!
298 : // TString path=id.GetPath();
299 : // if(AliCDBManager::Instance()->IsShortLived(path.Data())) {
300 : // AliInfo(Form("Tagging %s as short lived", dirName.Data()));
301 : // if(!TagShortLived(dirName, kTRUE)){
302 : // AliError(Form("Could not tag folder %s !", dirName.Data()));
303 : // if(!gGrid->Rmdir(dirName.Data())){
304 : // AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
305 : // }
306 : // return 0;
307 : // }
308 : // } else {
309 : // AliInfo(Form("Tagging %s as long lived", dirName.Data()));
310 : // if(!TagShortLived(dirName, kFALSE)){
311 : // AliError(Form("Could not tag folder %s !", dirName.Data()));
312 : // if(!gGrid->Rmdir(dirName.Data())){
313 : // AliError(Form("Unexpected: could not remove %s directory!", dirName.Data()));
314 : // }
315 : // return 0;
316 : // }
317 : // }
318 : }
319 : }
320 : }
321 0 : gGrid->Cd(initDir,0);
322 :
323 0 : TString filename;
324 0 : AliCDBId anId; // the id got from filename
325 0 : AliCDBRunRange lastRunRange(-1,-1); // highest runRange found
326 : Int_t lastVersion=0; // highest version found
327 :
328 0 : TGridResult *res = gGrid->Ls(dirName);
329 :
330 : //loop on the files in the directory, look for highest version
331 0 : for(int i=0; i < res->GetEntries(); i++){
332 0 : filename=res->GetFileNamePath(i);
333 0 : if (!FilenameToId(filename, anId)) continue;
334 0 : if (anId.GetAliCDBRunRange().Overlaps(id.GetAliCDBRunRange()) && anId.GetVersion() > lastVersion) {
335 0 : lastVersion = anId.GetVersion();
336 0 : lastRunRange = anId.GetAliCDBRunRange();
337 : }
338 :
339 : }
340 0 : delete res;
341 :
342 : // GRP entries with explicitly set version escape default incremental versioning
343 0 : if(id.GetPath().Contains("GRP") && id.HasVersion() && lastVersion!=0)
344 : {
345 0 : AliDebug(5,Form("Entry %s won't be put in the destination OCDB", id.ToString().Data()));
346 0 : return kFALSE;
347 : }
348 :
349 0 : id.SetVersion(lastVersion + 1);
350 0 : id.SetSubVersion(0);
351 :
352 0 : TString lastStorage = id.GetLastStorage();
353 0 : if(lastStorage.Contains(TString("new"), TString::kIgnoreCase) && id.GetVersion() > 1 ){
354 0 : AliDebug(2, Form("A NEW object is being stored with version %d",
355 : id.GetVersion()));
356 0 : AliDebug(2, Form("and it will hide previously stored object with version %d!",
357 : id.GetVersion()-1));
358 : }
359 :
360 0 : if(!lastRunRange.IsAnyRange() && !(lastRunRange.IsEqual(&id.GetAliCDBRunRange())))
361 0 : AliWarning(Form("Run range modified w.r.t. previous version (Run%d_%d_v%d)",
362 : lastRunRange.GetFirstRun(), lastRunRange.GetLastRun(), id.GetVersion()));
363 :
364 : return kTRUE;
365 0 : }
366 :
367 : //_____________________________________________________________________________
368 : AliCDBId* AliCDBGrid::GetId(const TObjArray& validFileIds, const AliCDBId& query) {
369 : // look for the Id that matches query's requests (highest or exact version)
370 :
371 0 : if(validFileIds.GetEntriesFast() < 1)
372 0 : return NULL;
373 :
374 0 : TIter iter(&validFileIds);
375 :
376 : AliCDBId *anIdPtr=0;
377 : AliCDBId* result=0;
378 :
379 0 : while((anIdPtr = dynamic_cast<AliCDBId*> (iter.Next()))){
380 0 : if(anIdPtr->GetPath() != query.GetPath()) continue;
381 :
382 : //if(!CheckVersion(query, anIdPtr, result)) return NULL;
383 :
384 0 : if (!query.HasVersion()){ // look for highest version
385 0 : if(result && result->GetVersion() > anIdPtr->GetVersion()) continue;
386 0 : if(result && result->GetVersion() == anIdPtr->GetVersion()) {
387 0 : AliError(Form("More than one object valid for run %d, version %d!",
388 : query.GetFirstRun(), anIdPtr->GetVersion()));
389 0 : return NULL;
390 : }
391 0 : result = new AliCDBId(*anIdPtr);
392 0 : } else { // look for specified version
393 0 : if(query.GetVersion() != anIdPtr->GetVersion()) continue;
394 0 : if(result && result->GetVersion() == anIdPtr->GetVersion()){
395 0 : AliError(Form("More than one object valid for run %d, version %d!",
396 : query.GetFirstRun(), anIdPtr->GetVersion()));
397 0 : return NULL;
398 : }
399 0 : result = new AliCDBId(*anIdPtr);
400 : }
401 :
402 : }
403 :
404 0 : return result;
405 0 : }
406 :
407 : //_____________________________________________________________________________
408 : AliCDBId* AliCDBGrid::GetEntryId(const AliCDBId& queryId) {
409 : // get AliCDBId from the database
410 : // User must delete returned object
411 :
412 : AliCDBId* dataId=0;
413 :
414 0 : AliCDBId selectedId(queryId);
415 0 : if (!selectedId.HasVersion()) {
416 : // if version is not specified, first check the selection criteria list
417 0 : GetSelection(&selectedId);
418 : }
419 :
420 0 : TObjArray validFileIds;
421 0 : validFileIds.SetOwner(1);
422 :
423 : // look for file matching query requests (path, runRange, version)
424 0 : if(selectedId.GetFirstRun() == fRun && fPathFilter.Comprises(selectedId.GetAliCDBPath()) &&
425 0 : fVersion == selectedId.GetVersion() && !fMetaDataFilter){
426 : // look into list of valid files previously loaded with AliCDBStorage::FillValidFileIds()
427 0 : AliDebug(2, Form("List of files valid for run %d was loaded. Looking there for fileids valid for path %s!",
428 : selectedId.GetFirstRun(), selectedId.GetPath().Data()));
429 0 : dataId = GetId(fValidFileIds, selectedId);
430 :
431 0 : } else {
432 : // List of files valid for reqested run was not loaded. Looking directly into CDB
433 0 : AliDebug(2, Form("List of files valid for run %d and version %d was not loaded. Looking directly into CDB for fileids valid for path %s!",
434 : selectedId.GetFirstRun(), selectedId.GetVersion(), selectedId.GetPath().Data()));
435 :
436 0 : TString filter;
437 0 : MakeQueryFilter(selectedId.GetFirstRun(), selectedId.GetLastRun(), 0, filter);
438 :
439 0 : TString pattern = ".root";
440 0 : TString optionQuery = "-y -m";
441 0 : if(selectedId.GetVersion() >= 0) {
442 0 : pattern.Prepend(Form("_v%d_s0",selectedId.GetVersion()));
443 0 : optionQuery = "";
444 : }
445 :
446 0 : TString folderCopy(Form("%s%s/Run",fDBFolder.Data(),selectedId.GetPath().Data()));
447 :
448 0 : if (optionQuery.Contains("-y")){
449 0 : AliInfo("Only latest version will be returned");
450 : }
451 :
452 0 : AliDebug(2,Form("** fDBFolder = %s, pattern = %s, filter = %s",folderCopy.Data(), pattern.Data(), filter.Data()));
453 0 : TGridResult *res = gGrid->Query(folderCopy, pattern, filter, optionQuery.Data());
454 0 : if (res) {
455 0 : for(int i=0; i<res->GetEntries(); i++){
456 0 : AliCDBId *validFileId = new AliCDBId();
457 0 : TString filename = res->GetKey(i, "lfn");
458 0 : if(filename == "") continue;
459 0 : if(FilenameToId(filename, *validFileId))
460 0 : validFileIds.AddLast(validFileId);
461 0 : }
462 0 : delete res;
463 : }else{
464 0 : return 0; // this should be only in case of file catalogue glitch
465 : }
466 :
467 0 : dataId = GetId(validFileIds, selectedId);
468 0 : }
469 :
470 0 : return dataId;
471 0 : }
472 :
473 : //_____________________________________________________________________________
474 : AliCDBEntry* AliCDBGrid::GetEntry(const AliCDBId& queryId) {
475 : // get AliCDBEntry from the database
476 :
477 0 : AliCDBId* dataId = GetEntryId(queryId);
478 :
479 0 : if (!dataId){
480 0 : AliFatal(TString::Format("No valid CDB object found! request was: %s", queryId.ToString().Data()));
481 0 : return NULL;
482 : }
483 :
484 0 : TString filename;
485 0 : if (!IdToFilename(*dataId, filename)) {
486 0 : AliDebug(2,Form("Bad data ID encountered! Subnormal error!"));
487 0 : delete dataId;
488 0 : AliFatal(TString::Format("No valid CDB object found! request was: %s", queryId.ToString().Data()));
489 0 : }
490 :
491 0 : AliCDBEntry* anEntry = GetEntryFromFile(filename, dataId);
492 :
493 0 : delete dataId;
494 0 : if(!anEntry)
495 0 : AliFatal(TString::Format("No valid CDB object found! request was: %s", queryId.ToString().Data()));
496 :
497 : return anEntry;
498 0 : }
499 :
500 : //_____________________________________________________________________________
501 : AliCDBEntry* AliCDBGrid::GetEntryFromFile(TString& filename, AliCDBId* dataId){
502 : // Get AliCBEntry object from file "filename"
503 :
504 0 : AliDebug(2,Form("Opening file: %s",filename.Data()));
505 :
506 0 : filename.Prepend("/alien");
507 :
508 : // if option="CACHEREAD" TFile will use the local caching facility!
509 0 : TString option="READ";
510 0 : if(fCacheFolder != ""){
511 :
512 : // Check if local cache folder was changed in the meanwhile
513 0 : TString origCache(TFile::GetCacheFileDir());
514 0 : if(fCacheFolder != origCache) {
515 0 : AliWarning(Form("Local cache folder has been overwritten!! fCacheFolder = %s origCache = %s",
516 : fCacheFolder.Data(), origCache.Data()));
517 0 : TFile::SetCacheFileDir(fCacheFolder.Data(), fOperateDisconnected);
518 0 : TFile::ShrinkCacheFileDir(fCacheSize, fCleanupInterval);
519 : }
520 :
521 0 : option.Prepend("CACHE");
522 0 : }
523 :
524 0 : AliDebug(2, Form("Option: %s", option.Data()));
525 :
526 0 : TFile *file = TFile::Open(filename, option);
527 0 : if (!file) {
528 0 : AliDebug(2,Form("Can't open file <%s>!", filename.Data()));
529 0 : return NULL;
530 : }
531 :
532 : // get the only AliCDBEntry object from the file
533 : // the object in the file is an AliCDBEntry entry named "AliCDBEntry"
534 :
535 0 : AliCDBEntry* anEntry = dynamic_cast<AliCDBEntry*> (file->Get("AliCDBEntry"));
536 :
537 0 : if (!anEntry) {
538 0 : AliDebug(2,Form("Bad storage data: file does not contain an AliCDBEntry object!"));
539 0 : file->Close();
540 0 : return NULL;
541 : }
542 :
543 : // The object's Id is not reset during storage
544 : // If object's Id runRange or version do not match with filename,
545 : // it means that someone renamed file by hand. In this case a warning msg is issued.
546 :
547 0 : if(anEntry){
548 0 : AliCDBId entryId = anEntry->GetId();
549 0 : Int_t tmpSubVersion = dataId->GetSubVersion();
550 0 : dataId->SetSubVersion(entryId.GetSubVersion()); // otherwise filename and id may mismatch
551 0 : if(!entryId.IsEqual(dataId)){
552 0 : AliWarning(Form("Mismatch between file name and object's Id!"));
553 0 : AliWarning(Form("File name: %s", dataId->ToString().Data()));
554 0 : AliWarning(Form("Object's Id: %s", entryId.ToString().Data()));
555 0 : }
556 0 : dataId->SetSubVersion(tmpSubVersion);
557 0 : }
558 :
559 0 : anEntry->SetLastStorage("grid");
560 :
561 : // Check whether entry contains a TTree. In case load the tree in memory!
562 0 : LoadTreeFromFile(anEntry);
563 :
564 : // close file, return retieved entry
565 0 : file->Close(); delete file; file=0;
566 :
567 0 : return anEntry;
568 0 : }
569 :
570 : //_____________________________________________________________________________
571 : TList* AliCDBGrid::GetEntries(const AliCDBId& queryId) {
572 : // multiple request (AliCDBStorage::GetAll)
573 :
574 0 : TList* result = new TList();
575 0 : result->SetOwner();
576 :
577 0 : TObjArray validFileIds;
578 0 : validFileIds.SetOwner(1);
579 :
580 : Bool_t alreadyLoaded = kFALSE;
581 :
582 : // look for file matching query requests (path, runRange)
583 0 : if(queryId.GetFirstRun() == fRun &&
584 0 : fPathFilter.Comprises(queryId.GetAliCDBPath()) && fVersion < 0 && !fMetaDataFilter){
585 : // look into list of valid files previously loaded with AliCDBStorage::FillValidFileIds()
586 0 : AliDebug(2,Form("List of files valid for run %d and for path %s was loaded. Looking there!",
587 : queryId.GetFirstRun(), queryId.GetPath().Data()));
588 :
589 : alreadyLoaded = kTRUE;
590 :
591 0 : } else {
592 : // List of files valid for reqested run was not loaded. Looking directly into CDB
593 0 : AliDebug(2,Form("List of files valid for run %d and for path %s was not loaded. Looking directly into CDB!",
594 : queryId.GetFirstRun(), queryId.GetPath().Data()));
595 :
596 0 : TString filter;
597 0 : MakeQueryFilter(queryId.GetFirstRun(), queryId.GetLastRun(), 0, filter);
598 :
599 0 : TString path = queryId.GetPath();
600 :
601 0 : TString pattern = "Run*.root";
602 0 : TString optionQuery = "-y";
603 :
604 0 : TString addFolder = "";
605 0 : if (!path.Contains("*")){
606 0 : if (!path.BeginsWith("/")) addFolder += "/";
607 0 : addFolder += path;
608 : }
609 : else{
610 0 : if (path.BeginsWith("/")) path.Remove(0,1);
611 0 : if (path.EndsWith("/")) path.Remove(path.Length()-1,1);
612 0 : TObjArray* tokenArr = path.Tokenize("/");
613 0 : if (tokenArr->GetEntries() != 3) {
614 0 : AliError("Not a 3 level path! Keeping old query...");
615 0 : pattern.Prepend(path+"/");
616 0 : }
617 : else{
618 0 : TString str0 = ((TObjString*)tokenArr->At(0))->String();
619 0 : TString str1 = ((TObjString*)tokenArr->At(1))->String();
620 0 : TString str2 = ((TObjString*)tokenArr->At(2))->String();
621 0 : if (str0 != "*" && str1 != "*" && str2 == "*"){
622 : // e.g. "ITS/Calib/*"
623 0 : addFolder = "/"+str0+"/"+str1;
624 0 : }
625 0 : else if (str0 != "*" && str1 == "*" && str2 == "*"){
626 : // e.g. "ITS/*/*"
627 0 : addFolder = "/"+str0;
628 0 : }
629 0 : else if (str0 == "*" && str1 == "*" && str2 == "*"){
630 : // e.g. "*/*/*"
631 : // do nothing: addFolder is already an empty string;
632 : }
633 : else{
634 : // e.g. "ITS/*/RecoParam"
635 0 : pattern.Prepend(path+"/");
636 : }
637 0 : }
638 0 : delete tokenArr; tokenArr=0;
639 : }
640 :
641 0 : TString folderCopy(Form("%s%s",fDBFolder.Data(),addFolder.Data()));
642 :
643 0 : AliDebug(2,Form("fDBFolder = %s, pattern = %s, filter = %s",folderCopy.Data(), pattern.Data(), filter.Data()));
644 :
645 0 : TGridResult *res = gGrid->Query(folderCopy, pattern, filter, optionQuery.Data());
646 :
647 0 : if (!res) {
648 0 : AliError("Grid query failed");
649 0 : return 0;
650 : }
651 :
652 0 : for(int i=0; i<res->GetEntries(); i++){
653 0 : AliCDBId *validFileId = new AliCDBId();
654 0 : TString filename = res->GetKey(i, "lfn");
655 0 : if(filename == "") continue;
656 0 : if(FilenameToId(filename, *validFileId))
657 0 : validFileIds.AddLast(validFileId);
658 0 : }
659 0 : delete res;
660 0 : }
661 :
662 : TIter *iter=0;
663 0 : if(alreadyLoaded){
664 0 : iter = new TIter(&fValidFileIds);
665 0 : } else {
666 0 : iter = new TIter(&validFileIds);
667 : }
668 :
669 0 : TObjArray selectedIds;
670 0 : selectedIds.SetOwner(1);
671 :
672 : // loop on list of valid Ids to select the right version to get.
673 : // According to query and to the selection criteria list, version can be the highest or exact
674 0 : AliCDBPath pathCopy;
675 : AliCDBId* anIdPtr=0;
676 : AliCDBId* dataId=0;
677 0 : AliCDBPath queryPath = queryId.GetAliCDBPath();
678 0 : while((anIdPtr = dynamic_cast<AliCDBId*> (iter->Next()))){
679 0 : AliCDBPath thisCDBPath = anIdPtr->GetAliCDBPath();
680 0 : if(!(queryPath.Comprises(thisCDBPath)) || pathCopy.GetPath() == thisCDBPath.GetPath()) continue;
681 0 : pathCopy = thisCDBPath;
682 :
683 : // check the selection criteria list for this query
684 0 : AliCDBId thisId(*anIdPtr);
685 0 : thisId.SetVersion(queryId.GetVersion());
686 0 : if(!thisId.HasVersion()) GetSelection(&thisId);
687 :
688 0 : if(alreadyLoaded){
689 0 : dataId = GetId(fValidFileIds, thisId);
690 0 : } else {
691 0 : dataId = GetId(validFileIds, thisId);
692 : }
693 0 : if(dataId) selectedIds.Add(dataId);
694 0 : }
695 :
696 0 : delete iter; iter=0;
697 :
698 : // selectedIds contains the Ids of the files matching all requests of query!
699 : // All the objects are now ready to be retrieved
700 0 : iter = new TIter(&selectedIds);
701 0 : while((anIdPtr = dynamic_cast<AliCDBId*> (iter->Next()))){
702 0 : TString filename;
703 0 : if (!IdToFilename(*anIdPtr, filename)) {
704 0 : AliDebug(2,Form("Bad data ID encountered! Subnormal error!"));
705 0 : continue;
706 : }
707 :
708 0 : AliCDBEntry* anEntry = GetEntryFromFile(filename, anIdPtr);
709 :
710 0 : if(anEntry) result->Add(anEntry);
711 :
712 0 : }
713 0 : delete iter; iter=0;
714 :
715 : return result;
716 0 : }
717 :
718 : //_____________________________________________________________________________
719 : Bool_t AliCDBGrid::PutEntry(AliCDBEntry* entry, const char* mirrors) {
720 : // put an AliCDBEntry object into the database
721 :
722 0 : AliCDBId& id = entry->GetId();
723 :
724 : // set version for the entry to be stored
725 0 : if (!PrepareId(id)) return kFALSE;
726 :
727 : // build filename from entry's id
728 0 : TString filename;
729 0 : if (!IdToFilename(id, filename)) {
730 0 : AliError("Bad ID encountered, cannot make a file name out of it!");
731 0 : return kFALSE;
732 : }
733 :
734 0 : TString folderToTag = Form("%s%s",
735 0 : fDBFolder.Data(),
736 0 : id.GetPath().Data());
737 :
738 0 : TDirectory* saveDir = gDirectory;
739 :
740 0 : TString fullFilename = Form("/alien%s", filename.Data());
741 0 : TString seMirrors(mirrors);
742 0 : if(seMirrors.IsNull() || seMirrors.IsWhitespace()) seMirrors=GetMirrorSEs();
743 : // specify SE to filename
744 : // if a list of SEs was passed to this method or set via SetMirrorSEs, set the first as SE for opening the file.
745 : // The other SEs will be used in cascade in case of failure in opening the file.
746 : // The remaining SEs will be used to create replicas.
747 0 : TObjArray *arraySEs = seMirrors.Tokenize(',');
748 0 : Int_t nSEs = arraySEs->GetEntries();
749 : Int_t remainingSEs = 1;
750 0 : if(nSEs == 0){
751 0 : if (fSE != "default") fullFilename += Form("?se=%s",fSE.Data());
752 : }else{
753 : remainingSEs = nSEs;
754 : }
755 :
756 : // open file
757 : TFile *file = 0;
758 : TFile *reopenedFile = 0;
759 0 : AliDebug(2, Form("fNretry = %d, fInitRetrySeconds = %d",fNretry,fInitRetrySeconds));
760 0 : TString targetSE("");
761 :
762 : Bool_t result = kFALSE;
763 : Bool_t reOpenResult = kFALSE;
764 : Int_t reOpenAttempts=0;
765 0 : while( !reOpenResult && reOpenAttempts<2 ) { //loop to check the file after closing it, to catch the unlikely but possible case when the file
766 : // is cleaned up by alien just before closing as a consequence of a network disconnection while writing
767 :
768 0 : while( !file && remainingSEs>0 ) {
769 0 : if(nSEs!=0){
770 0 : TObjString *target = (TObjString*) arraySEs->At(nSEs-remainingSEs);
771 0 : targetSE=target->String();
772 0 : if ( !(targetSE.BeginsWith("ALICE::") && targetSE.CountChar(':')==4) ) {
773 0 : AliError( Form("\"%s\" is an invalid storage element identifier.",targetSE.Data()) );
774 0 : continue;
775 : }
776 0 : if ( fullFilename.Contains('?')) fullFilename.Remove(fullFilename.Last('?') );
777 0 : fullFilename += Form("?se=%s",targetSE.Data());
778 0 : }
779 0 : Int_t remainingAttempts=fNretry;
780 0 : Int_t nsleep = fInitRetrySeconds; // number of seconds between attempts. We let it increase exponentially
781 0 : AliDebug(2, Form("Uploading file into SE #%d: %s",nSEs-remainingSEs+1,targetSE.Data()));
782 0 : while(remainingAttempts > 0) {
783 0 : AliDebug(2, Form("Uploading file into OCDB at %s - Attempt #%d",targetSE.Data(),fNretry-remainingAttempts+1));
784 0 : remainingAttempts--;
785 0 : file = TFile::Open(fullFilename,"CREATE");
786 0 : if(!file || !file->IsWritable()){
787 0 : if(file) { // file is not writable
788 0 : file->Close(); delete file; file=0;
789 0 : }
790 0 : TString message(TString::Format("Attempt %d failed.",fNretry-remainingAttempts));
791 0 : if(remainingAttempts>0) {
792 0 : message += " Sleeping for "; message += nsleep; message += " seconds";
793 : }else{
794 0 : if(remainingSEs>0) message += " Trying to upload at next SE";
795 : }
796 0 : AliDebug(2, message.Data());
797 0 : if(remainingAttempts>0) sleep(nsleep);
798 0 : }else{
799 : remainingAttempts=0;
800 : }
801 0 : nsleep*=fInitRetrySeconds;
802 : }
803 0 : remainingSEs--;
804 : }
805 0 : if(!file){
806 0 : AliError(Form("All %d attempts have failed on all %d SEs. Returning...",fNretry,nSEs));
807 0 : return kFALSE;
808 : }
809 :
810 0 : file->cd();
811 :
812 : //SetTreeToFile(entry, file);
813 0 : entry->SetVersion(id.GetVersion());
814 :
815 : // write object (key name: "AliCDBEntry")
816 0 : result = (file->WriteTObject(entry, "AliCDBEntry") != 0);
817 0 : file->Close();
818 0 : if (!result) {
819 0 : AliError(Form("Can't write entry to file <%s>!", filename.Data()));
820 : } else {
821 0 : AliDebug(2, Form("Reopening file %s for checking its correctness",fullFilename.Data()));
822 0 : reopenedFile = TFile::Open(fullFilename.Data(),"READ");
823 0 : if(!reopenedFile){
824 : reOpenResult = kFALSE;
825 0 : AliInfo(Form("The file %s was closed successfully but cannot be reopened. Trying now to regenerate it (regeneration attempt number %d)",
826 : fullFilename.Data(),++reOpenAttempts));
827 0 : delete file; file=0;
828 0 : AliDebug(2, Form("Removing file %s", filename.Data()));
829 0 : if(!gGrid->Rm(filename.Data()))
830 0 : AliError("Can't delete file!");
831 0 : remainingSEs++;
832 0 : }else{
833 : reOpenResult = kTRUE;
834 0 : if ( ! AliCDBManager::Instance()->IsOCDBUploadMode() ) {
835 0 : reopenedFile->Close();
836 0 : delete reopenedFile; reopenedFile=0;
837 0 : }
838 : }
839 : }
840 : }
841 :
842 0 : if (saveDir) saveDir->cd(); else gROOT->cd();
843 0 : delete file; file=0;
844 :
845 0 : if(result && reOpenResult) {
846 :
847 0 : if(!TagFileId(filename, &id)){
848 0 : AliInfo(Form("CDB tagging failed. Deleting file %s!",filename.Data()));
849 0 : if(!gGrid->Rm(filename.Data()))
850 0 : AliError("Can't delete file!");
851 0 : return kFALSE;
852 : }
853 :
854 0 : TagFileMetaData(filename, entry->GetMetaData());
855 : }else{
856 0 : AliError("The file could not be opened or the object could not be written.");
857 0 : if(!gGrid->Rm(filename.Data()))
858 0 : AliError("Can't delete file!");
859 0 : return kFALSE;
860 : }
861 :
862 0 : AliInfo(Form("CDB object stored into file %s", filename.Data()));
863 0 : if(nSEs==0)
864 0 : AliInfo(Form("Storage Element: %s", fSE.Data()));
865 : else
866 0 : AliInfo(Form("Storage Element: %s", targetSE.Data()));
867 :
868 : //In case of other SEs specified by the user, mirror the file to the remaining SEs
869 0 : for(Int_t i=0; i<nSEs; i++){
870 0 : if(i==nSEs-remainingSEs-1) continue; // skip mirroring to the SE where the file was saved
871 0 : TString mirrorCmd("mirror ");
872 0 : mirrorCmd += filename;
873 0 : mirrorCmd += " ";
874 0 : TObjString *target = (TObjString*) arraySEs->At(i);
875 0 : TString mirrorSE(target->String());
876 0 : mirrorCmd += mirrorSE;
877 0 : AliDebug(5,Form("mirror command: \"%s\"",mirrorCmd.Data()));
878 0 : AliInfo(Form("Mirroring to storage element: %s", mirrorSE.Data()));
879 0 : gGrid->Command(mirrorCmd.Data());
880 0 : }
881 0 : arraySEs->Delete(); arraySEs=0;
882 :
883 0 : if ( AliCDBManager::Instance()->IsOCDBUploadMode() ) { // if uploading to OCDBs, add to cvmfs too
884 0 : if ( !filename.BeginsWith("/alice/data") && !filename.BeginsWith("/alice/simulation/2008/v4-15-Release") ) {
885 0 : AliError ( Form ( "Cannot upload to CVMFS OCDBs a non official CDB object: \"%s\"!", filename.Data() ) );
886 : } else {
887 0 : if ( !PutInCvmfs( filename, reopenedFile) )
888 0 : AliError( Form( "Could not upload AliEn file \"%s\" to CVMFS OCDB!", filename.Data() ) );
889 : }
890 0 : reopenedFile->Close();
891 0 : delete reopenedFile; reopenedFile=0;
892 0 : }
893 :
894 0 : return kTRUE;
895 0 : }
896 :
897 : //_____________________________________________________________________________
898 : Bool_t AliCDBGrid::PutInCvmfs( TString& filename, TFile* cdbFile ) const
899 : {
900 : // Add the CDB object to cvmfs OCDB
901 :
902 0 : TString cvmfsFilename( filename );
903 : // cvmfsFilename.Remove(TString::kTrailing, '/');
904 0 : TString basename = ( cvmfsFilename( cvmfsFilename.Last( '/' ) + 1, cvmfsFilename.Length() ) );
905 0 : TString cvmfsDirname = cvmfsFilename.Remove( cvmfsFilename.Last( '/' ), cvmfsFilename.Length() );
906 0 : TRegexp threeLevelsRE( "[^/]+/[^/]+/[^/]+$" );
907 0 : TString threeLevels = cvmfsDirname( threeLevelsRE );
908 :
909 0 : TRegexp re_RawFolder("^/alice/data/20[0-9]+/OCDB");
910 0 : TRegexp re_MCFolder("^/alice/simulation/2008/v4-15-Release");
911 0 : TString rawFolder = cvmfsDirname(re_RawFolder);
912 0 : TString mcFolder = cvmfsDirname(re_MCFolder);
913 0 : if ( !rawFolder.IsNull() ) {
914 0 : cvmfsDirname.Replace(0, 6, "/cvmfs/alice-ocdb.cern.ch/calibration");
915 0 : } else if ( !mcFolder.IsNull() ){
916 0 : cvmfsDirname.Replace(0,36,"/cvmfs/alice-ocdb.cern.ch/calibration/MC");
917 : } else {
918 0 : AliError(Form("OCDB folder set for an invalid OCDB storage:\n %s", cvmfsDirname.Data()));
919 0 : return kFALSE;
920 : }
921 : // now cvmfsDirname is the full dirname in cvmfs
922 0 : AliDebug(3, Form("Publishing \"%s\" in \"%s\"", basename.Data(), cvmfsDirname.Data()));
923 :
924 : // Tar the file with the right prefix path. Include the directory structure in the tarball
925 : // to cover the case of a containing directory being new in cvmfs, plus a container directory
926 : // to avoid clashing with stuff present in the local directory
927 0 : TString firstLevel(threeLevels(0, threeLevels.First('/')));
928 0 : TString tempDir("tmpToCvmfsOcdbs");
929 0 : gSystem->Exec( Form("rm -r %s > /dev/null 2>&1", tempDir.Data()) ); //to be sure not to publish other stuff in cvmfs
930 0 : Int_t result = gSystem->Exec( Form("mkdir -p %s/%s", tempDir.Data(), threeLevels.Data()) );
931 0 : if ( result != 0 ) {
932 0 : AliError ( Form ( "Could not create the directory \"%s/%s\"", tempDir.Data(), threeLevels.Data() ) );
933 0 : return kFALSE;
934 : }
935 0 : cdbFile->Cp(Form("%s/%s/%s", tempDir.Data(), threeLevels.Data(), basename.Data() ));
936 0 : TString tarFileName("cdbObjectToAdd.tar.gz");
937 0 : TString cvmfsBaseFolder(cvmfsDirname(0, cvmfsDirname.Last('/')));
938 0 : cvmfsBaseFolder = cvmfsBaseFolder(0, cvmfsBaseFolder.Last('/'));
939 0 : cvmfsBaseFolder = cvmfsBaseFolder(0, cvmfsBaseFolder.Last('/'));
940 : // tarCommand should be e.g.: tar --transform 's,^,/cvmfs/alice-ocdb.cern.ch/calibration/data/2010/OCDB/,S' -cvzf objecttoadd.tar.gz basename
941 0 : result = gSystem->Exec ( Form( "tar --transform 's,^%s,%s,S' -cvzf %s %s", tempDir.Data(), cvmfsBaseFolder.Data(), tarFileName.Data(), tempDir.Data() ) );
942 0 : if ( result != 0 ) {
943 0 : AliError ( Form ( "Could not create the tarball for the object \"%s\"", filename.Data() ) );
944 0 : return kFALSE;
945 : }
946 :
947 : // Copy the file to cvmfs (requires to have the executable in the path and access to the server)
948 0 : result = gSystem->Exec( Form( "ocdb-cvmfs %s", tarFileName.Data() ) );
949 0 : if ( result != 0 ) {
950 0 : AliError ( Form ( "Could not execute \"ocdb-cvmfs %s\"", filename.Data() ) );
951 0 : return kFALSE;
952 : }
953 :
954 : // Remove the local file and the tar-file
955 0 : gSystem->Exec( Form( "rm -r %s", tempDir.Data() ) );
956 0 : gSystem->Exec( Form( "rm %s", tarFileName.Data() ) );
957 :
958 0 : return kTRUE;
959 0 : }
960 :
961 : //_____________________________________________________________________________
962 : Bool_t AliCDBGrid::AddTag(TString& folderToTag, const char* tagname){
963 : // add "tagname" tag (CDB or CDB_MD) to folder where object will be stored
964 :
965 : Bool_t result = kTRUE;
966 0 : AliDebug(2, Form("adding %s tag to folder %s", tagname, folderToTag.Data()));
967 0 : TString addTag = Form("addTag %s %s", folderToTag.Data(), tagname);
968 0 : TGridResult *gridres = gGrid->Command(addTag.Data());
969 0 : const char* resCode = gridres->GetKey(0,"__result__"); // '1' if success
970 0 : if(resCode[0] != '1') {
971 0 : AliError(Form("Couldn't add %s tags to folder %s !",
972 : tagname, folderToTag.Data()));
973 : result = kFALSE;
974 0 : }
975 0 : delete gridres;
976 0 : return result;
977 0 : }
978 :
979 : //_____________________________________________________________________________
980 : Bool_t AliCDBGrid::TagFileId(TString& filename, const AliCDBId* id){
981 : // tag stored object in CDB table using object Id's parameters
982 :
983 :
984 0 : TString dirname(filename);
985 0 : Int_t dirNumber = gGrid->Mkdir(dirname.Remove(dirname.Last('/')),"-d");
986 :
987 0 : TString addTagValue1 = Form("addTagValue %s CDB ", filename.Data());
988 0 : TString addTagValue2 = Form("first_run=%d last_run=%d version=%d ",
989 0 : id->GetFirstRun(),
990 0 : id->GetLastRun(),
991 0 : id->GetVersion());
992 0 : TString addTagValue3 = Form("path_level_0=\"%s\" path_level_1=\"%s\" path_level_2=\"%s\" ",
993 0 : id->GetPathLevel(0).Data(),
994 0 : id->GetPathLevel(1).Data(),
995 0 : id->GetPathLevel(2).Data());
996 : //TString addTagValue4 = Form("version_path=\"%s\" dir_number=%d",Form("%d_%s",id->GetVersion(),filename.Data()),dirNumber);
997 0 : TString addTagValue4 = Form("version_path=\"%09d%s\" dir_number=%d",id->GetVersion(),filename.Data(),dirNumber);
998 0 : TString addTagValue = Form("%s%s%s%s",
999 0 : addTagValue1.Data(),
1000 0 : addTagValue2.Data(),
1001 0 : addTagValue3.Data(),
1002 0 : addTagValue4.Data());
1003 :
1004 : Bool_t result = kFALSE;
1005 0 : AliDebug(2, Form("Tagging file. Tag command: %s", addTagValue.Data()));
1006 0 : TGridResult* res = gGrid->Command(addTagValue.Data());
1007 0 : const char* resCode = res->GetKey(0,"__result__"); // '1' if success
1008 0 : if(resCode[0] != '1') {
1009 0 : AliError(Form("Couldn't add CDB tag value to file %s !",
1010 : filename.Data()));
1011 : result = kFALSE;
1012 0 : } else {
1013 0 : AliDebug(2, "Object successfully tagged.");
1014 : result = kTRUE;
1015 : }
1016 0 : delete res;
1017 0 : return result;
1018 :
1019 0 : }
1020 :
1021 : //_____________________________________________________________________________
1022 : Bool_t AliCDBGrid::TagShortLived(TString& filename, Bool_t value){
1023 : // tag folder with ShortLived tag
1024 :
1025 0 : TString addTagValue = Form("addTagValue %s ShortLived_try value=%d", filename.Data(), value);
1026 :
1027 : Bool_t result = kFALSE;
1028 0 : AliDebug(2, Form("Tagging file. Tag command: %s", addTagValue.Data()));
1029 0 : TGridResult* res = gGrid->Command(addTagValue.Data());
1030 0 : const char* resCode = res->GetKey(0,"__result__"); // '1' if success
1031 0 : if(resCode[0] != '1') {
1032 0 : AliError(Form("Couldn't add ShortLived tag value to file %s !", filename.Data()));
1033 : result = kFALSE;
1034 0 : } else {
1035 0 : AliDebug(2,"Object successfully tagged.");
1036 : result = kTRUE;
1037 : }
1038 0 : delete res;
1039 0 : return result;
1040 :
1041 0 : }
1042 :
1043 : //_____________________________________________________________________________
1044 : Bool_t AliCDBGrid::TagFileMetaData(TString& filename, const AliCDBMetaData* md){
1045 : // tag stored object in CDB table using object Id's parameters
1046 :
1047 0 : TString addTagValue1 = Form("addTagValue %s CDB_MD ", filename.Data());
1048 0 : TString addTagValue2 = Form("object_classname=\"%s\" responsible=\"%s\" beam_period=%d ",
1049 0 : md->GetObjectClassName(),
1050 0 : md->GetResponsible(),
1051 0 : md->GetBeamPeriod());
1052 0 : TString addTagValue3 = Form("aliroot_version=\"%s\" comment=\"%s\"",
1053 0 : md->GetAliRootVersion(),
1054 0 : md->GetComment());
1055 0 : TString addTagValue = Form("%s%s%s",
1056 0 : addTagValue1.Data(),
1057 0 : addTagValue2.Data(),
1058 0 : addTagValue3.Data());
1059 :
1060 : Bool_t result = kFALSE;
1061 0 : AliDebug(2, Form("Tagging file. Tag command: %s", addTagValue.Data()));
1062 0 : TGridResult* res = gGrid->Command(addTagValue.Data());
1063 0 : const char* resCode = res->GetKey(0,"__result__"); // '1' if success
1064 0 : if(resCode[0] != '1') {
1065 0 : AliWarning(Form("Couldn't add CDB_MD tag value to file %s !",
1066 : filename.Data()));
1067 : result = kFALSE;
1068 0 : } else {
1069 0 : AliDebug(2,"Object successfully tagged.");
1070 : result = kTRUE;
1071 : }
1072 0 : return result;
1073 0 : }
1074 :
1075 : //_____________________________________________________________________________
1076 : TList* AliCDBGrid::GetIdListFromFile(const char* fileName){
1077 :
1078 0 : TString turl(fileName);
1079 0 : turl.Prepend("/alien" + fDBFolder);
1080 0 : turl += "?se="; turl += fSE.Data();
1081 0 : TFile *file = TFile::Open(turl);
1082 0 : if (!file) {
1083 0 : AliError(Form("Can't open selection file <%s>!", turl.Data()));
1084 0 : return NULL;
1085 : }
1086 :
1087 0 : TList *list = new TList();
1088 0 : list->SetOwner();
1089 : int i=0;
1090 0 : TString keycycle;
1091 :
1092 : AliCDBId *id;
1093 0 : while(1){
1094 0 : i++;
1095 0 : keycycle = "AliCDBId;";
1096 0 : keycycle+=i;
1097 :
1098 0 : id = (AliCDBId*) file->Get(keycycle);
1099 0 : if(!id) break;
1100 0 : list->AddFirst(id);
1101 : }
1102 0 : file->Close(); delete file; file=0;
1103 :
1104 : return list;
1105 :
1106 :
1107 0 : }
1108 :
1109 : //_____________________________________________________________________________
1110 : Bool_t AliCDBGrid::Contains(const char* path) const{
1111 : // check for path in storage's DBFolder
1112 :
1113 0 : TString initDir(gGrid->Pwd(0));
1114 0 : TString dirName(fDBFolder);
1115 0 : dirName += path; // dirName = fDBFolder/path
1116 : Bool_t result=kFALSE;
1117 0 : if (gGrid->Cd(dirName,0)) result=kTRUE;
1118 0 : gGrid->Cd(initDir.Data(),0);
1119 0 : return result;
1120 0 : }
1121 :
1122 : //_____________________________________________________________________________
1123 : void AliCDBGrid::QueryValidFiles()
1124 : {
1125 : // Query the CDB for files valid for AliCDBStorage::fRun
1126 : // Fills list fValidFileIds with AliCDBId objects extracted from CDB files
1127 : // selected from AliEn metadata.
1128 : // If fVersion was not set, fValidFileIds is filled with highest versions.
1129 :
1130 0 : TString filter;
1131 0 : MakeQueryFilter(fRun, fRun, fMetaDataFilter, filter);
1132 :
1133 0 : TString path = fPathFilter.GetPath();
1134 :
1135 0 : TString pattern = "Run*";
1136 0 : TString optionQuery = "-y";
1137 0 : if(fVersion >= 0) {
1138 0 : pattern += Form("_v%d_s0", fVersion);
1139 0 : optionQuery = "";
1140 : }
1141 0 : pattern += ".root";
1142 0 : AliDebug(2,Form("pattern: %s", pattern.Data()));
1143 :
1144 0 : TString addFolder = "";
1145 0 : if (!path.Contains("*")){
1146 0 : if (!path.BeginsWith("/")) addFolder += "/";
1147 0 : addFolder += path;
1148 : }
1149 : else{
1150 0 : if (path.BeginsWith("/")) path.Remove(0,1);
1151 0 : if (path.EndsWith("/")) path.Remove(path.Length()-1,1);
1152 0 : TObjArray* tokenArr = path.Tokenize("/");
1153 0 : if (tokenArr->GetEntries() != 3) {
1154 0 : AliError("Not a 3 level path! Keeping old query...");
1155 0 : pattern.Prepend(path+"/");
1156 0 : }
1157 : else{
1158 0 : TString str0 = ((TObjString*)tokenArr->At(0))->String();
1159 0 : TString str1 = ((TObjString*)tokenArr->At(1))->String();
1160 0 : TString str2 = ((TObjString*)tokenArr->At(2))->String();
1161 0 : if (str0 != "*" && str1 != "*" && str2 == "*"){
1162 : // e.g. "ITS/Calib/*"
1163 0 : addFolder = "/"+str0+"/"+str1;
1164 0 : }
1165 0 : else if (str0 != "*" && str1 == "*" && str2 == "*"){
1166 : // e.g. "ITS/*/*"
1167 0 : addFolder = "/"+str0;
1168 0 : }
1169 0 : else if (str0 == "*" && str1 == "*" && str2 == "*"){
1170 : // e.g. "*/*/*"
1171 : // do nothing: addFolder is already an empty string;
1172 : }
1173 : else{
1174 : // e.g. "ITS/*/RecoParam"
1175 0 : pattern.Prepend(path+"/");
1176 : }
1177 0 : }
1178 0 : delete tokenArr; tokenArr=0;
1179 : }
1180 :
1181 0 : TString folderCopy(Form("%s%s",fDBFolder.Data(),addFolder.Data()));
1182 :
1183 0 : AliDebug(2,Form("fDBFolder = %s, pattern = %s, filter = %s",folderCopy.Data(), pattern.Data(), filter.Data()));
1184 :
1185 0 : if (optionQuery == "-y"){
1186 0 : AliInfo("Only latest version will be returned");
1187 : }
1188 :
1189 0 : TGridResult *res = gGrid->Query(folderCopy, pattern, filter, optionQuery.Data());
1190 :
1191 0 : if (!res) {
1192 0 : AliError("Grid query failed");
1193 0 : return;
1194 : }
1195 :
1196 0 : TIter next(res);
1197 : TMap *map;
1198 0 : while ((map = (TMap*)next())) {
1199 : TObjString *entry;
1200 0 : if ((entry = (TObjString *) ((TMap *)map)->GetValue("lfn"))) {
1201 0 : TString& filename = entry->String();
1202 0 : if(filename.IsNull()) continue;
1203 0 : AliDebug(2,Form("Found valid file: %s", filename.Data()));
1204 0 : AliCDBId *validFileId = new AliCDBId();
1205 0 : Bool_t result = FilenameToId(filename, *validFileId);
1206 0 : if(result) {
1207 0 : fValidFileIds.AddLast(validFileId);
1208 : }
1209 : else {
1210 0 : delete validFileId;
1211 : }
1212 0 : }
1213 0 : }
1214 0 : delete res;
1215 :
1216 0 : }
1217 :
1218 : //_____________________________________________________________________________
1219 : void AliCDBGrid::MakeQueryFilter(Int_t firstRun, Int_t lastRun,
1220 : const AliCDBMetaData* md, TString& result) const
1221 : {
1222 : // create filter for file query
1223 :
1224 0 : result = Form("CDB:first_run<=%d and CDB:last_run>=%d", firstRun, lastRun);
1225 :
1226 : // if(version >= 0) {
1227 : // result += Form(" and CDB:version=%d", version);
1228 : // }
1229 : // if(pathFilter.GetLevel0() != "*") {
1230 : // result += Form(" and CDB:path_level_0=\"%s\"", pathFilter.GetLevel0().Data());
1231 : // }
1232 : // if(pathFilter.GetLevel1() != "*") {
1233 : // result += Form(" and CDB:path_level_1=\"%s\"", pathFilter.GetLevel1().Data());
1234 : // }
1235 : // if(pathFilter.GetLevel2() != "*") {
1236 : // result += Form(" and CDB:path_level_2=\"%s\"", pathFilter.GetLevel2().Data());
1237 : // }
1238 :
1239 0 : if(md){
1240 0 : if(md->GetObjectClassName()[0] != '\0') {
1241 0 : result += Form(" and CDB_MD:object_classname=\"%s\"", md->GetObjectClassName());
1242 0 : }
1243 0 : if(md->GetResponsible()[0] != '\0') {
1244 0 : result += Form(" and CDB_MD:responsible=\"%s\"", md->GetResponsible());
1245 0 : }
1246 0 : if(md->GetBeamPeriod() != 0) {
1247 0 : result += Form(" and CDB_MD:beam_period=%d", md->GetBeamPeriod());
1248 0 : }
1249 0 : if(md->GetAliRootVersion()[0] != '\0') {
1250 0 : result += Form(" and CDB_MD:aliroot_version=\"%s\"", md->GetAliRootVersion());
1251 0 : }
1252 0 : if(md->GetComment()[0] != '\0') {
1253 0 : result += Form(" and CDB_MD:comment=\"%s\"", md->GetComment());
1254 0 : }
1255 : }
1256 0 : AliDebug(2, Form("filter: %s",result.Data()));
1257 :
1258 0 : }
1259 :
1260 :
1261 : /////////////////////////////////////////////////////////////////////////////////////////////////
1262 : // //
1263 : // AliCDBGrid factory //
1264 : // //
1265 : /////////////////////////////////////////////////////////////////////////////////////////////////
1266 :
1267 128 : ClassImp(AliCDBGridFactory)
1268 :
1269 : //_____________________________________________________________________________
1270 : Bool_t AliCDBGridFactory::Validate(const char* gridString) {
1271 : // check if the string is valid Grid URI
1272 :
1273 32 : TRegexp gridPattern("^alien://.+$");
1274 :
1275 48 : return TString(gridString).Contains(gridPattern);
1276 16 : }
1277 :
1278 : //_____________________________________________________________________________
1279 : AliCDBParam* AliCDBGridFactory::CreateParameter(const char* gridString) {
1280 : // create AliCDBGridParam class from the URI string
1281 :
1282 32 : if (!Validate(gridString)) {
1283 0 : return NULL;
1284 : }
1285 :
1286 16 : TString buffer(gridString);
1287 :
1288 16 : TString gridUrl = "alien://";
1289 16 : TString user = "";
1290 16 : TString dbFolder = "";
1291 16 : TString se = "default";
1292 16 : TString cacheFolder = "";
1293 : Bool_t operateDisconnected = kTRUE;
1294 : Long64_t cacheSize = (UInt_t) 1024*1024*1024; // 1GB
1295 : Long_t cleanupInterval = 0;
1296 :
1297 48 : TObjArray *arr = buffer.Tokenize('?');
1298 16 : TIter iter(arr);
1299 : TObjString *str = 0;
1300 :
1301 112 : while((str = (TObjString*) iter.Next())){
1302 32 : TString entry(str->String());
1303 96 : Int_t indeq = entry.Index('=');
1304 32 : if(indeq == -1) {
1305 0 : if(entry.BeginsWith("alien://")) { // maybe it's a gridUrl!
1306 0 : gridUrl = entry;
1307 0 : continue;
1308 : } else {
1309 0 : AliError(Form("Invalid entry! %s",entry.Data()));
1310 0 : continue;
1311 : }
1312 : }
1313 :
1314 64 : TString key = entry(0,indeq);
1315 96 : TString value = entry(indeq+1,entry.Length()-indeq);
1316 :
1317 64 : if(key.Contains("grid",TString::kIgnoreCase)) {
1318 0 : gridUrl += value;
1319 : }
1320 64 : else if (key.Contains("user",TString::kIgnoreCase)){
1321 16 : user = value;
1322 : }
1323 32 : else if (key.Contains("se",TString::kIgnoreCase)){
1324 0 : se = value;
1325 : }
1326 32 : else if (key.Contains("cacheF",TString::kIgnoreCase)){
1327 0 : cacheFolder = value;
1328 0 : if (!cacheFolder.IsNull() && !cacheFolder.EndsWith("/"))
1329 0 : cacheFolder += "/";
1330 : }
1331 32 : else if (key.Contains("folder",TString::kIgnoreCase)){
1332 16 : dbFolder = value;
1333 : }
1334 0 : else if (key.Contains("operateDisc",TString::kIgnoreCase)){
1335 0 : if(value == "kTRUE") {
1336 : operateDisconnected = kTRUE;
1337 0 : } else if (value == "kFALSE") {
1338 : operateDisconnected = kFALSE;
1339 0 : } else if (value == "0" || value == "1") {
1340 0 : operateDisconnected = (Bool_t) value.Atoi();
1341 : } else {
1342 0 : AliError(Form("Invalid entry! %s",entry.Data()));
1343 0 : return NULL;
1344 : }
1345 : }
1346 0 : else if (key.Contains("cacheS",TString::kIgnoreCase)){
1347 0 : if(value.IsDigit()) {
1348 0 : cacheSize = value.Atoi();
1349 : } else {
1350 0 : AliError(Form("Invalid entry! %s",entry.Data()));
1351 0 : return NULL;
1352 : }
1353 0 : }
1354 0 : else if (key.Contains("cleanupInt",TString::kIgnoreCase)){
1355 0 : if(value.IsDigit()) {
1356 0 : cleanupInterval = value.Atoi();
1357 : } else {
1358 0 : AliError(Form("Invalid entry! %s",entry.Data()));
1359 0 : return NULL;
1360 : }
1361 : }
1362 : else{
1363 0 : AliError(Form("Invalid entry! %s",entry.Data()));
1364 0 : return NULL;
1365 : }
1366 96 : }
1367 32 : delete arr; arr=0;
1368 :
1369 80 : AliDebug(2, Form("gridUrl: %s", gridUrl.Data()));
1370 80 : AliDebug(2, Form("user: %s", user.Data()));
1371 80 : AliDebug(2, Form("dbFolder: %s", dbFolder.Data()));
1372 80 : AliDebug(2, Form("s.e.: %s", se.Data()));
1373 80 : AliDebug(2, Form("local cache folder: %s", cacheFolder.Data()));
1374 80 : AliDebug(2, Form("local cache operate disconnected: %d", operateDisconnected));
1375 80 : AliDebug(2, Form("local cache size: %lld", cacheSize));
1376 80 : AliDebug(2, Form("local cache cleanup interval: %ld", cleanupInterval));
1377 :
1378 32 : if(dbFolder == ""){
1379 0 : AliError("Base folder must be specified!");
1380 0 : return NULL;
1381 : }
1382 :
1383 80 : return new AliCDBGridParam(gridUrl.Data(), user.Data(),
1384 48 : dbFolder.Data(), se.Data(), cacheFolder.Data(),
1385 16 : operateDisconnected, cacheSize, cleanupInterval);
1386 32 : }
1387 :
1388 : //_____________________________________________________________________________
1389 : AliCDBStorage* AliCDBGridFactory::Create(const AliCDBParam* param) {
1390 : // create AliCDBGrid storage instance from parameters
1391 :
1392 : AliCDBGrid *grid = 0;
1393 0 : if (AliCDBGridParam::Class() == param->IsA()) {
1394 :
1395 0 : const AliCDBGridParam* gridParam = (const AliCDBGridParam*) param;
1396 0 : grid = new AliCDBGrid(gridParam->GridUrl().Data(),
1397 0 : gridParam->GetUser().Data(),
1398 0 : gridParam->GetDBFolder().Data(),
1399 0 : gridParam->GetSE().Data(),
1400 0 : gridParam->GetCacheFolder().Data(),
1401 0 : gridParam->GetOperateDisconnected(),
1402 0 : gridParam->GetCacheSize(),
1403 0 : gridParam->GetCleanupInterval());
1404 :
1405 0 : }
1406 :
1407 0 : if(!gGrid && grid) {
1408 0 : delete grid; grid=0;
1409 0 : }
1410 :
1411 0 : return grid;
1412 0 : }
1413 :
1414 : /////////////////////////////////////////////////////////////////////////////////////////////////
1415 : // //
1416 : // AliCDBGrid Parameter class // //
1417 : // //
1418 : /////////////////////////////////////////////////////////////////////////////////////////////////
1419 :
1420 128 : ClassImp(AliCDBGridParam)
1421 :
1422 : //_____________________________________________________________________________
1423 : AliCDBGridParam::AliCDBGridParam():
1424 0 : AliCDBParam(),
1425 0 : fGridUrl(),
1426 0 : fUser(),
1427 0 : fDBFolder(),
1428 0 : fSE(),
1429 0 : fCacheFolder(),
1430 0 : fOperateDisconnected(),
1431 0 : fCacheSize(),
1432 0 : fCleanupInterval()
1433 :
1434 0 : {
1435 : // default constructor
1436 :
1437 0 : }
1438 :
1439 : //_____________________________________________________________________________
1440 : AliCDBGridParam::AliCDBGridParam(const char* gridUrl, const char* user, const char* dbFolder,
1441 : const char* se, const char* cacheFolder, Bool_t operateDisconnected,
1442 : Long64_t cacheSize, Long_t cleanupInterval):
1443 16 : AliCDBParam(),
1444 16 : fGridUrl(gridUrl),
1445 16 : fUser(user),
1446 16 : fDBFolder(dbFolder),
1447 16 : fSE(se),
1448 16 : fCacheFolder(cacheFolder),
1449 16 : fOperateDisconnected(operateDisconnected),
1450 16 : fCacheSize(cacheSize),
1451 16 : fCleanupInterval(cleanupInterval)
1452 48 : {
1453 : // constructor
1454 :
1455 16 : SetType("alien");
1456 :
1457 48 : TString uri = Form("%s?User=%s?DBFolder=%s?SE=%s?CacheFolder=%s"
1458 : "?OperateDisconnected=%d?CacheSize=%lld?CleanupInterval=%ld",
1459 32 : fGridUrl.Data(), fUser.Data(),
1460 48 : fDBFolder.Data(), fSE.Data(), fCacheFolder.Data(),
1461 16 : fOperateDisconnected, fCacheSize, fCleanupInterval);
1462 :
1463 32 : SetURI(uri.Data());
1464 32 : }
1465 :
1466 : //_____________________________________________________________________________
1467 12 : AliCDBGridParam::~AliCDBGridParam() {
1468 : // destructor
1469 :
1470 6 : }
1471 :
1472 : //_____________________________________________________________________________
1473 : AliCDBParam* AliCDBGridParam::CloneParam() const {
1474 : // clone parameter
1475 :
1476 0 : return new AliCDBGridParam(fGridUrl.Data(), fUser.Data(),
1477 0 : fDBFolder.Data(), fSE.Data(), fCacheFolder.Data(),
1478 0 : fOperateDisconnected, fCacheSize, fCleanupInterval);
1479 0 : }
1480 :
1481 : //_____________________________________________________________________________
1482 : ULong_t AliCDBGridParam::Hash() const {
1483 : // return Hash function
1484 :
1485 0 : return fGridUrl.Hash()+fUser.Hash()+fDBFolder.Hash()+fSE.Hash()+fCacheFolder.Hash();
1486 : }
1487 :
1488 : //_____________________________________________________________________________
1489 : Bool_t AliCDBGridParam::IsEqual(const TObject* obj) const {
1490 : // check if this object is equal to AliCDBParam obj
1491 :
1492 0 : if (this == obj) {
1493 0 : return kTRUE;
1494 : }
1495 :
1496 0 : if (AliCDBGridParam::Class() != obj->IsA()) {
1497 0 : return kFALSE;
1498 : }
1499 :
1500 0 : AliCDBGridParam* other = (AliCDBGridParam*) obj;
1501 :
1502 0 : if(fGridUrl != other->fGridUrl) return kFALSE;
1503 0 : if(fUser != other->fUser) return kFALSE;
1504 0 : if(fDBFolder != other->fDBFolder) return kFALSE;
1505 0 : if(fSE != other->fSE) return kFALSE;
1506 0 : if(fCacheFolder != other->fCacheFolder) return kFALSE;
1507 0 : if(fOperateDisconnected != other->fOperateDisconnected) return kFALSE;
1508 0 : if(fCacheSize != other->fCacheSize) return kFALSE;
1509 0 : if(fCleanupInterval != other->fCleanupInterval) return kFALSE;
1510 0 : return kTRUE;
1511 0 : }
1512 :
|