]> git.uio.no Git - u/mrichter/AliRoot.git/blame - SHUTTLE/AliShuttle.cxx
changing order of library loading
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttle.cxx
CommitLineData
73abe331 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$Log$
2bb7b766 18Revision 1.14 2006/08/29 09:16:05 jgrosseo
19small update
20
85a80aa9 21Revision 1.13 2006/08/15 10:50:00 jgrosseo
22effc++ corrections (alberto)
23
4f0ab988 24Revision 1.12 2006/08/08 14:19:29 jgrosseo
25Update to shuttle classes (Alberto)
26
27- Possibility to set the full object's path in the Preprocessor's and
28Shuttle's Store functions
29- Possibility to extend the object's run validity in the same classes
30("startValidity" and "validityInfinite" parameters)
31- Implementation of the StoreReferenceData function to store reference
32data in a dedicated CDB storage.
33
84090f85 34Revision 1.11 2006/07/21 07:37:20 jgrosseo
35last run is stored after each run
36
7bfb2090 37Revision 1.10 2006/07/20 09:54:40 jgrosseo
38introducing status management: The processing per subdetector is divided into several steps,
39after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
40can keep track of the number of failures and skips further processing after a certain threshold is
41exceeded. These thresholds can be configured in LDAP.
42
5164a766 43Revision 1.9 2006/07/19 10:09:55 jgrosseo
44new configuration, accesst to DAQ FES (Alberto)
45
57f50b3c 46Revision 1.8 2006/07/11 12:44:36 jgrosseo
47adding parameters for extended validity range of data produced by preprocessor
48
17111222 49Revision 1.7 2006/07/10 14:37:09 jgrosseo
50small fix + todo comment
51
e090413b 52Revision 1.6 2006/07/10 13:01:41 jgrosseo
53enhanced storing of last sucessfully processed run (alberto)
54
a7160fe9 55Revision 1.5 2006/07/04 14:59:57 jgrosseo
56revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
57
45a493ce 58Revision 1.4 2006/06/12 09:11:16 jgrosseo
59coding conventions (Alberto)
60
58bc3020 61Revision 1.3 2006/06/06 14:26:40 jgrosseo
62o) removed files that were moved to STEER
63o) shuttle updated to follow the new interface (Alberto)
64
b948db8d 65Revision 1.2 2006/03/07 07:52:34 hristov
66New version (B.Yordanov)
67
d477ad88 68Revision 1.6 2005/11/19 17:19:14 byordano
69RetrieveDATEEntries and RetrieveConditionsData added
70
71Revision 1.5 2005/11/19 11:09:27 byordano
72AliShuttle declaration added
73
74Revision 1.4 2005/11/17 17:47:34 byordano
75TList changed to TObjArray
76
77Revision 1.3 2005/11/17 14:43:23 byordano
78import to local CVS
79
80Revision 1.1.1.1 2005/10/28 07:33:58 hristov
81Initial import as subdirectory in AliRoot
82
73abe331 83Revision 1.2 2005/09/13 08:41:15 byordano
84default startTime endTime added
85
86Revision 1.4 2005/08/30 09:13:02 byordano
87some docs added
88
89Revision 1.3 2005/08/29 21:15:47 byordano
90some docs added
91
92*/
93
94//
95// This class is the main manager for AliShuttle.
96// It organizes the data retrieval from DCS and call the
b948db8d 97// interface methods of AliPreprocessor.
73abe331 98// For every detector in AliShuttleConfgi (see AliShuttleConfig),
99// data for its set of aliases is retrieved. If there is registered
b948db8d 100// AliPreprocessor for this detector then it will be used
101// accroding to the schema (see AliPreprocessor).
102// If there isn't registered AliPreprocessor than the retrieved
73abe331 103// data is stored automatically to the undelying AliCDBStorage.
104// For detSpec is used the alias name.
105//
106
107#include "AliShuttle.h"
108
109#include "AliCDBManager.h"
110#include "AliCDBStorage.h"
111#include "AliCDBId.h"
84090f85 112#include "AliCDBRunRange.h"
113#include "AliCDBPath.h"
5164a766 114#include "AliCDBEntry.h"
73abe331 115#include "AliShuttleConfig.h"
116#include "AliDCSClient.h"
117#include "AliLog.h"
b948db8d 118#include "AliPreprocessor.h"
5164a766 119#include "AliShuttleStatus.h"
2bb7b766 120#include "AliShuttleLogbookEntry.h"
73abe331 121
57f50b3c 122#include <TSystem.h>
58bc3020 123#include <TObject.h>
b948db8d 124#include <TString.h>
57f50b3c 125#include <TTimeStamp.h>
73abe331 126#include <TObjString.h>
57f50b3c 127#include <TSQLServer.h>
128#include <TSQLResult.h>
129#include <TSQLRow.h>
73abe331 130
5164a766 131#include <fstream>
132
73abe331 133ClassImp(AliShuttle)
134
2bb7b766 135TString AliShuttle::fgkMainCDB("alien://folder=ShuttleCDB");
84090f85 136TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
2bb7b766 137TString AliShuttle::fgkMainRefStorage("alien://folder=ShuttleReference");
84090f85 138TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
139
4f0ab988 140Bool_t AliShuttle::fgkProcessDCS(kTRUE);
141
142
84090f85 143const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
144const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
57f50b3c 145
2bb7b766 146const char* AliShuttle::fgkDetectorName[AliShuttle::kNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
57f50b3c 147 "PHOS", "CPV", "RICH", "EMCAL", "MUON_TRK", "MUON_TRG", "FMD", "ZDC", "PMD", "START", "VZERO"};
148
2bb7b766 149const char* AliShuttle::fgkDetectorCode[AliShuttle::kNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
57f50b3c 150 "PHS", "CPV", "HMP", "EMC", "MCH", "MTR", "FMD", "ZDC", "PMD", "T00", "V00"};
b948db8d 151
152//______________________________________________________________________________________________
153AliShuttle::AliShuttle(const AliShuttleConfig* config,
154 UInt_t timeout, Int_t retries):
4f0ab988 155fConfig(config),
156fTimeout(timeout), fRetries(retries),
157fPreprocessorMap(),
2bb7b766 158fLogbookEntry(0),
4f0ab988 159fCurrentDetector(""),
85a80aa9 160fStatusEntry(0),
161fGridError(kFALSE)
73abe331 162{
163 //
164 // config: AliShuttleConfig used
73abe331 165 // timeout: timeout used for AliDCSClient connection
166 // retries: the number of retries in case of connection error.
167 //
168
57f50b3c 169 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
170 for(int iSys=0;iSys<3;iSys++) {
171 fServer[iSys]=0;
172 fFESlist[iSys].SetOwner(kTRUE);
173 }
2bb7b766 174 fPreprocessorMap.SetOwner(kTRUE);
73abe331 175}
176
58bc3020 177//______________________________________________________________________
178AliShuttle::AliShuttle(const AliShuttle& /*other*/):
4f0ab988 179AliShuttleInterface(),
180fConfig(0),
181fTimeout(0), fRetries(0),
182fPreprocessorMap(),
2bb7b766 183fLogbookEntry(0),
4f0ab988 184fCurrentDetector(""),
85a80aa9 185fStatusEntry(0),
186fGridError(kFALSE)
58bc3020 187{
188// copy constructor (not implemented)
189
190}
191
192//______________________________________________________________________
193AliShuttle &AliShuttle::operator=(const AliShuttle& /*other*/)
194{
195// assignment operator (not implemented)
196
197return *this;
198}
199
b948db8d 200//______________________________________________________________________________________________
57f50b3c 201AliShuttle::~AliShuttle()
58bc3020 202{
203// destructor
204
b948db8d 205 fPreprocessorMap.DeleteAll();
57f50b3c 206 for(int iSys=0;iSys<3;iSys++)
207 if(fServer[iSys]) {
208 fServer[iSys]->Close();
209 delete fServer[iSys];
210 }
2bb7b766 211
212 if (fStatusEntry){
213 delete fStatusEntry;
214 fStatusEntry = 0;
215 }
73abe331 216}
217
b948db8d 218//______________________________________________________________________________________________
57f50b3c 219void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
58bc3020 220{
73abe331 221 //
b948db8d 222 // Registers new AliPreprocessor.
73abe331 223 // It uses GetName() for indentificator of the pre processor.
224 // The pre processor is registered it there isn't any other
225 // with the same identificator (GetName()).
226 //
227
b948db8d 228 if (fPreprocessorMap.GetValue(preprocessor->GetName())) {
229 AliWarning(Form("AliPreprocessor %s is already registered!",
230 preprocessor->GetName()));
73abe331 231 return;
232 }
233
b948db8d 234 fPreprocessorMap.Add(new TObjString(preprocessor->GetName()), preprocessor);
73abe331 235}
b948db8d 236//______________________________________________________________________________________________
84090f85 237UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
238 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
73abe331 239{
84090f85 240 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
241 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
242 // using this function. Use StoreReferenceData instead!
85a80aa9 243 // It calls WriteToCDB function which perform actual storage
b948db8d 244
85a80aa9 245 return WriteToCDB(fgkMainCDB, fgkLocalCDB, path, object,
246 metaData, validityStart, validityInfinite);
84090f85 247
248}
249
250//______________________________________________________________________________________________
251UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object,
252 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
253{
254 // Stores a CDB object in the storage for reference data. This objects will not be available during
255 // offline reconstrunction. Use this function for reference data only!
85a80aa9 256 // It calls WriteToCDB function which perform actual storage
257
258 return WriteToCDB(fgkMainRefStorage, fgkLocalRefStorage, path, object,
259 metaData, validityStart, validityInfinite);
84090f85 260
85a80aa9 261}
262
263//______________________________________________________________________________________________
264UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
265 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
266 Int_t validityStart, Bool_t validityInfinite)
267{
268 // write object into the CDB. Parameters are passed by Store and StoreReferenceData functions.
269 // The parameters are:
270 // 1) Uri of the main storage (Grid)
271 // 2) Uri of the backup storage (Local)
272 // 3) the object's path.
273 // 4) the object to be stored
274 // 5) the metaData to be associated with the object
275 // 6) the validity start run number w.r.t. the current run,
84090f85 276 // if the data is valid only for this run leave the default 0
85a80aa9 277 // 7) specifies if the calibration data is valid for infinity (this means until updated),
84090f85 278 // typical for calibration runs, the default is kFALSE
279 //
84090f85 280 // returns 0 if fail
85a80aa9 281 // 1 if stored in main (Grid) storage
282 // 2 if stored in backup (Local) storage
84090f85 283
85a80aa9 284 const char* cdbType = (mainUri == fgkMainCDB) ? "CDB" : "Reference";
2bb7b766 285
85a80aa9 286 Int_t firstRun = GetCurrentRun() - validityStart;
84090f85 287 if(firstRun < 0) {
2bb7b766 288 AliError("First valid run happens to be less than 0! Setting it to 0.");
84090f85 289 firstRun=0;
290 }
291
292 Int_t lastRun = -1;
293 if(validityInfinite) {
294 lastRun = AliCDBRunRange::Infinity();
295 } else {
296 lastRun = GetCurrentRun();
297 }
298
2bb7b766 299 AliCDBId id(path, firstRun, lastRun, -1, -1);
300
301 if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
302 TObjString runUsed = Form("%d", GetCurrentRun());
303 metaData->SetProperty("RunUsed(TObjString)",&runUsed);
304 }
84090f85 305
306 UInt_t result = 0;
307
85a80aa9 308 if (!(AliCDBManager::Instance()->GetStorage(mainUri))) {
2bb7b766 309 AliError(Form("WriteToCDB - Cannot activate main %s storage", cdbType));
84090f85 310 } else {
85a80aa9 311 result = (UInt_t) AliCDBManager::Instance()->GetStorage(mainUri)
84090f85 312 ->Put(object, id, metaData);
313 }
314
315 if(!result) {
316
317 Log(fCurrentDetector,
2bb7b766 318 Form("WriteToCDB - Problem with main %s storage. Putting <%s> into backup storage",
319 cdbType, path.GetPath().Data()));
320
321 // Set Grid version to current run number, to ease retrieval later
322 id.SetVersion(GetCurrentRun());
84090f85 323
85a80aa9 324 result = AliCDBManager::Instance()->GetStorage(localUri)
84090f85 325 ->Put(object, id, metaData);
326
327 if(result) {
328 result = 2;
85a80aa9 329 fGridError = kTRUE;
84090f85 330 }else{
2bb7b766 331 Log(fCurrentDetector, "WriteToCDB - Can't store data!");
b948db8d 332 }
333 }
2bb7b766 334
b948db8d 335 return result;
336
73abe331 337}
338
b948db8d 339//______________________________________________________________________________________________
5164a766 340AliShuttleStatus* AliShuttle::ReadShuttleStatus()
341{
2bb7b766 342// Reads the AliShuttleStatus from the CDB
5164a766 343
2bb7b766 344 if (fStatusEntry){
345 delete fStatusEntry;
346 fStatusEntry = 0;
347 }
5164a766 348
2bb7b766 349 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
350 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
5164a766 351
2bb7b766 352 if (!fStatusEntry) return 0;
353 fStatusEntry->SetOwner(1);
5164a766 354
2bb7b766 355 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
356 if (!status) {
357 AliError("Invalid object stored to CDB!");
358 return 0;
359 }
5164a766 360
2bb7b766 361 return status;
5164a766 362}
363
364//______________________________________________________________________________________________
7bfb2090 365Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
5164a766 366{
2bb7b766 367// writes the status for one subdetector
368
369 if (fStatusEntry){
370 delete fStatusEntry;
371 fStatusEntry = 0;
372 }
5164a766 373
2bb7b766 374 Int_t run = GetCurrentRun();
5164a766 375
2bb7b766 376 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
5164a766 377
2bb7b766 378 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
379 fStatusEntry->SetOwner(1);
5164a766 380
2bb7b766 381 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
7bfb2090 382
2bb7b766 383 if (!result) {
384 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), run));
385 return kFALSE;
386 }
7bfb2090 387
2bb7b766 388 return kTRUE;
5164a766 389}
390
391//______________________________________________________________________________________________
392void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
393{
394 // changes the AliShuttleStatus for the given detector and run to the given status
395
2bb7b766 396 if (!fStatusEntry){
397 AliError("UNEXPECTED: fStatusEntry empty");
398 return;
399 }
5164a766 400
2bb7b766 401 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
5164a766 402
2bb7b766 403 if (!status){
404 AliError("UNEXPECTED: status could not be read from current CDB entry");
405 return;
406 }
5164a766 407
2bb7b766 408 Log("SHUTTLE", Form("UpdateShuttleStatus - %s: Changing state from %s to %s", fCurrentDetector.Data(),
409 status->GetStatusName(), status->GetStatusName(newStatus)));
5164a766 410
2bb7b766 411 status->SetStatus(newStatus);
412 if (increaseCount) status->IncreaseCount();
5164a766 413
2bb7b766 414 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
5164a766 415}
5164a766 416//______________________________________________________________________________________________
417Bool_t AliShuttle::ContinueProcessing()
418{
2bb7b766 419// this function reads the AliShuttleStatus information from CDB and
420// checks if the processing should be continued
421// if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
422
423 if(!GetDetCode(fCurrentDetector)) {
424 Log("SHUTTLE", Form("ContinueProcessing - %s: unknown detector",
425 fCurrentDetector.Data()));
426 return kFALSE;
427 }
428
429 AliShuttleLogbookEntry::Status entryStatus =
430 fLogbookEntry->GetDetectorStatus(GetDetCode(fCurrentDetector));
431
432 if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
433 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s",
434 fCurrentDetector.Data(),
435 fLogbookEntry->GetDetectorStatusName(entryStatus)));
436 return kFALSE;
437 }
438
439 // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
440 AliShuttleStatus* status = ReadShuttleStatus();
441 if (!status) {
442 // first time
443 Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
444 fCurrentDetector.Data()));
445 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
446 return WriteShuttleStatus(status);
447 }
448
449 // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
450 // If it happens it may mean Logbook updating failed... let's do it now!
451 if (status->GetStatus() == AliShuttleStatus::kDone ||
452 status->GetStatus() == AliShuttleStatus::kFailed){
453 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
454 fCurrentDetector.Data(),
455 status->GetStatusName(status->GetStatus())));
456 UpdateShuttleLogbook(fCurrentDetector.Data(),
457 status->GetStatusName(status->GetStatus()));
458 return kFALSE;
459 }
460
461 if (status->GetStatus() == AliShuttleStatus::kStoreFailed) {
462 Log("SHUTTLE",
463 Form("ContinueProcessing - %s: Grid storage of one or more objects failed. Trying again now",
464 fCurrentDetector.Data()));
465 if(TryToStoreAgain()){
466 Log(fCurrentDetector.Data(), "ContinueProcessing - All objects successfully stored into OCDB");
467 UpdateShuttleStatus(AliShuttleStatus::kDone);
468 UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE");
469 } else {
470 Log("SHUTTLE",
471 Form("ContinueProcessing - %s: Grid storage failed again",
472 fCurrentDetector.Data()));
473 }
474 return kFALSE;
475 }
476
477 // if we get here, there is a restart
478
479 // abort conditions
480 // TODO we should add two counters, one for PP and one for DCS!
481 if ((status->GetStatus() == AliShuttleStatus::kPPStarted ||
482 status->GetStatus() == AliShuttleStatus::kPPError) &&
483 (status->GetCount() >= fConfig->GetMaxPPRetries() ||
484 status->GetCount() >= fConfig->GetMaxRetries())) {
485 Log("SHUTTLE",
486 Form("ContinueProcessing - %s failed %d times in status %s - Updating Shuttle Logbook",
487 fCurrentDetector.Data(),
488 status->GetCount(), status->GetStatusName()));
489 UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
490 return kFALSE;
491 }
492
493 Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. Got stuck before in %s. Retry number %d.",
494 fCurrentDetector.Data(),
495 status->GetStatusName(), status->GetCount()));
496
497 UpdateShuttleStatus(AliShuttleStatus::kStarted);
498
499 return kTRUE;
5164a766 500}
501
502//______________________________________________________________________________________________
2bb7b766 503Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
58bc3020 504{
73abe331 505 //
b948db8d 506 // Makes data retrieval for all detectors in the configuration.
2bb7b766 507 // entry: Shuttle logbook entry, contains run paramenters and status of detectors
508 // (Unprocessed, Inactive, Failed or Done).
d477ad88 509 // Returns kFALSE in case of error occured and kTRUE otherwise
73abe331 510 //
511
2bb7b766 512 if(!entry) return kFALSE;
513
514 fLogbookEntry = entry;
515
516 if(fLogbookEntry->IsDone()){
517 Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
518 UpdateShuttleLogbook("shuttle_done");
519 fLogbookEntry = 0;
520 return kTRUE;
521 }
522
523
524 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n",
525 GetCurrentRun()));
526
527 fLogbookEntry->Print("");
57f50b3c 528
529 // Initialization
d477ad88 530 Bool_t hasError = kFALSE;
57f50b3c 531 for(Int_t iSys=0;iSys<3;iSys++) fFESCalled[iSys]=kFALSE;
5164a766 532
2bb7b766 533 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
534 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
535 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
536 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
d477ad88 537
57f50b3c 538 // Loop on detectors in the configuration
b948db8d 539 TIter iter(fConfig->GetDetectors());
2bb7b766 540 TObjString* aDetector = 0;
b948db8d 541
73abe331 542 while ((aDetector = (TObjString*) iter.Next())) {
7bfb2090 543 fCurrentDetector = aDetector->String();
5164a766 544
5164a766 545 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
546
2bb7b766 547 AliPreprocessor* aPreprocessor =
548 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
549 if(!aPreprocessor){
550 Log("SHUTTLE",Form("Process - %s: no preprocessor registered. Skipping"));
551 continue;
552 }
553
7bfb2090 554 if (ContinueProcessing() == kFALSE) continue;
5164a766 555
2bb7b766 556 AliInfo(Form("\n\n \t\t\t****** run %d - %s: START ******",
557 GetCurrentRun(), aDetector->GetName()));
558
559 UInt_t result = ProcessCurrentDetector();
85a80aa9 560
2bb7b766 561 if(!result) {
d477ad88 562 hasError = kTRUE;
2bb7b766 563 AliInfo(Form("\n \t\t\t****** run %d - %s: PREPROCESSOR ERROR ****** \n\n",
564 GetCurrentRun(), aDetector->GetName()));
57f50b3c 565 continue;
d477ad88 566 }
2bb7b766 567
568 if(result == 2) {
569 AliInfo(Form("\n \t\t\t****** run %d - %s: STORAGE ERROR ****** \n\n",
570 GetCurrentRun(), aDetector->GetName()));
571 } else {
572 AliInfo(Form("\n \t\t\t****** run %d - %s: DONE ****** \n\n",
573 GetCurrentRun(), aDetector->GetName()));
574 }
57f50b3c 575
576 // Process successful: Update time_processed field in FES logbooks!
577 if(fFESCalled[kDAQ]) {
5164a766 578 hasError = (UpdateDAQTable() == kFALSE);
57f50b3c 579 fFESlist[kDAQ].Clear();
580 }
581 //if(fFESCalled[kDCS]) {
582 // hasError = UpdateDCSTable(aDetector->GetName());
583 // fFESlist[kDCS].Clear();
584 //}
585 //if(fFESCalled[kHLT]) {
586 // hasError = UpdateHLTTable(aDetector->GetName());
587 // fFESlist[kHLT].Clear();
588 //}
d477ad88 589
7bfb2090 590 }
5164a766 591
2bb7b766 592 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n",
593 GetCurrentRun()));
594
595 //check if shuttle is done for this run, if so update logbook
596 TObjArray checkEntryArray;
597 checkEntryArray.SetOwner(1);
598 TString whereClause = Form("where run=%d",GetCurrentRun());
599 if(QueryShuttleLogbook(whereClause.Data(), checkEntryArray)) {
b948db8d 600
2bb7b766 601 AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
602 (checkEntryArray.At(0));
603
604 if(checkEntry && checkEntry->IsDone()){
605 Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
606 UpdateShuttleLogbook("shuttle_done");
607 }
608 }
609
610 fLogbookEntry = 0;
85a80aa9 611
a7160fe9 612 return hasError == kFALSE;
73abe331 613}
614
b948db8d 615//______________________________________________________________________________________________
2bb7b766 616UInt_t AliShuttle::ProcessCurrentDetector()
73abe331 617{
618 //
2bb7b766 619 // Makes data retrieval just for a specific detector (fCurrentDetector).
73abe331 620 // Threre should be a configuration for this detector.
73abe331 621
2bb7b766 622 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), GetCurrentRun()));
73abe331 623
7bfb2090 624 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
73abe331 625
7bfb2090 626 TString host(fConfig->GetDCSHost(fCurrentDetector));
5164a766 627 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
628
629 TIter iter(fConfig->GetDCSAliases(fCurrentDetector));
73abe331 630 TObjString* anAlias;
b948db8d 631 TMap aliasMap;
2bb7b766 632 aliasMap.SetOwner(1);
73abe331 633
85a80aa9 634 Bool_t aDCSError = kFALSE;
635 fGridError = kFALSE;
d477ad88 636
b948db8d 637 while ((anAlias = (TObjString*) iter.Next())) {
2bb7b766 638 TObjArray *valueSet = new TObjArray();
639 valueSet->SetOwner(1);
4f0ab988 640 // TODO Test only... I've added a flag that allows to
641 // exclude DCS archive DB query
642 if(fgkProcessDCS){
643 AliInfo("Querying DCS archive DB data...");
85a80aa9 644 aDCSError = (GetValueSet(host, port, anAlias->String(), valueSet) == 0);
4f0ab988 645 } else {
646 AliInfo(Form("Skipping DCS processing. Port = %d",port));
85a80aa9 647 aDCSError = kFALSE;
4f0ab988 648 }
85a80aa9 649 if(!aDCSError) {
2bb7b766 650 aliasMap.Add(anAlias->Clone(), valueSet);
b948db8d 651 }else{
2bb7b766 652 Log(fCurrentDetector, Form("ProcessCurrentDetector - Error while retrieving alias %s",
653 anAlias->GetName()));
654 UpdateShuttleStatus(AliShuttleStatus::kDCSError, kTRUE);
655 aliasMap.DeleteAll();
656 return 0;
73abe331 657 }
658 }
b948db8d 659
2bb7b766 660 // DCS Archive DB processing successful. Call Preprocessor!
85a80aa9 661 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
a7160fe9 662
85a80aa9 663 AliPreprocessor* aPreprocessor =
5164a766 664 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
b948db8d 665
2bb7b766 666 aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
667
668 UInt_t aPPResult = aPreprocessor->Process(&aliasMap);
669
670 UInt_t returnValue = 0;
85a80aa9 671 if (aPPResult == 0) { // Preprocessor error
2bb7b766 672 UpdateShuttleStatus(AliShuttleStatus::kPPError, kTRUE);
673 returnValue = 0;
85a80aa9 674 } else if (fGridError == kFALSE) { // process and Grid storage ok!
675 UpdateShuttleStatus(AliShuttleStatus::kDone);
2bb7b766 676 UpdateShuttleLogbook(fCurrentDetector, "DONE");
677 Log(fCurrentDetector.Data(),
678 "ProcessCurrentDetector - Preprocessor and Grid storage ended successfully");
679 returnValue = 1;
85a80aa9 680 } else { // Grid storage error (process ok, but object put in local storage)
681 UpdateShuttleStatus(AliShuttleStatus::kStoreFailed);
2bb7b766 682 returnValue = 2;
85a80aa9 683 }
b948db8d 684
2bb7b766 685 aliasMap.DeleteAll();
b948db8d 686
2bb7b766 687 return returnValue;
688}
689
690//______________________________________________________________________________________________
691Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
692 TObjArray& entries)
693{
694// Query DAQ's Shuttle logbook and fills detector status object.
695// Call QueryRunParameters to query DAQ logbook for run parameters.
696
697 // check connection, in case connect
698 if(!Connect(kDAQ)) return kFALSE;
699
700 TString sqlQuery;
701 sqlQuery = Form("select * from logbook_shuttle %s order by run", whereClause);
702
703 TSQLResult* aResult = fServer[kDAQ]->Query(sqlQuery);
704 if (!aResult) {
705 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
706 return kFALSE;
707 }
708
709 if(aResult->GetRowCount() == 0) {
710 if(sqlQuery.Contains("where shuttle_done=0")){
711 Log("SHUTTLE", "QueryShuttleLogbook - All runs in Shuttle Logbook are already DONE");
712 delete aResult;
713 return kTRUE;
714 } else {
715 AliError("No entries in Shuttle Logbook match request");
716 delete aResult;
717 return kFALSE;
718 }
719 }
720
721 // TODO Check field count!
722 const UInt_t nCols = 24;
723 if (aResult->GetFieldCount() != (Int_t) nCols) {
724 AliError("Invalid SQL result field number!");
725 delete aResult;
726 return kFALSE;
727 }
728
729 entries.SetOwner(1);
730
731 TSQLRow* aRow;
732 while ((aRow = aResult->Next())) {
733 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
734 Int_t run = runString.Atoi();
735
736 UInt_t startTime, endTime;
737 if(!QueryRunParameters(run, startTime, endTime)) continue;
738
739 const UInt_t nDet = AliShuttle::kNDetectors;
740 AliShuttleLogbookEntry::Status detStatus[nDet];
741
742 // loop on detectors
743 for(UInt_t ii = 0; ii < nCols; ii++){
744 TString detCode(aResult->GetFieldName(ii));
745 Int_t detPos = AliShuttle::GetDetPos(detCode.Data());
746 if(detPos < 0) continue;
747 TString statusString(aRow->GetField(ii), aRow->GetFieldLength(ii));
748 if(statusString == "UNPROCESSED"){
749 detStatus[detPos] = AliShuttleLogbookEntry::kUnprocessed;
750 } else if (statusString == "INACTIVE") {
751 detStatus[detPos] = AliShuttleLogbookEntry::kInactive;
752 } else if (statusString == "FAILED") {
753 detStatus[detPos] = AliShuttleLogbookEntry::kFailed;
754 } else if (statusString == "DONE") {
755 detStatus[detPos] = AliShuttleLogbookEntry::kDone;
756 }
757 }
758
759 entries.AddLast(new AliShuttleLogbookEntry(run, startTime, endTime, detStatus));
760 delete aRow;
761 }
762
763 if(sqlQuery.Contains("where shuttle_done=0"))
764 Log("SHUTTLE", Form("QueryShuttleLogbook - Found %d unprocessed runs in Shuttle Logbook",
765 entries.GetEntriesFast()));
766 delete aResult;
767 return kTRUE;
768}
769
770//______________________________________________________________________________________________
771Bool_t AliShuttle::QueryRunParameters(Int_t& run, UInt_t& startTime, UInt_t& endTime)
772{
773// Retrieve start time and end time for run in the DAQ logbook
774
775 // check connection, in case connect
776 if(!Connect(kDAQ)) return kFALSE;
777
778 TString sqlQuery;
779 sqlQuery = Form("select time_start, time_end from logbook where run=%d", run);
780
781 TSQLResult* aResult = fServer[kDAQ]->Query(sqlQuery);
782 if (!aResult) {
783 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
784 return kFALSE;
785 }
786
787 if(aResult->GetRowCount() == 0) {
788 Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
789 delete aResult;
790 return kFALSE;
791 }
792
793 if(aResult->GetRowCount() > 1) {
794 AliError(Form("More than one entry in DAQ Logbook for run %d. Skipping", run));
795 delete aResult;
796 return kFALSE;
797 }
798
799 TSQLRow* aRow;
800 while ((aRow = aResult->Next())) {
801
802 TString startTimeString(aRow->GetField(0),
803 aRow->GetFieldLength(0));
804 startTime = startTimeString.Atoi();
805 TString endTimeString(aRow->GetField(1),
806 aRow->GetFieldLength(1));
807 endTime = endTimeString.Atoi();
808
809 if (!startTime || !endTime || startTime > endTime) {
810 Log("SHUTTLE",
811 Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d",
812 run, startTime, endTime));
813 delete aRow;
814 delete aResult;
815 return kFALSE;
816 }
817
818 delete aRow;
819 }
820
821 delete aResult;
822 return kTRUE;
823}
824
825//______________________________________________________________________________________________
826Bool_t AliShuttle::TryToStoreAgain()
827{
828 // Called in case the detector failed to store the object in Grid OCDB
829 // It tries to store the object again, if it does not find more recent and overlapping objects
830 // Calls underlying TryToStoreAgain(const char*) function twice, for OCDB and Reference storage.
831
832 AliInfo("Trying to store OCDB data again...");
833 Bool_t resultCDB = TryToStoreAgain(fgkMainCDB);
834
835 AliInfo("Trying to store reference data again...");
836 Bool_t resultRef = TryToStoreAgain(fgkMainRefStorage);
837
838 return resultCDB && resultRef;
839}
840
841//______________________________________________________________________________________________
842Bool_t AliShuttle::TryToStoreAgain(TString& gridURI)
843{
844 // Called by TryToStoreAgain(), performs actual storage retry
845
846 TList* gridIds=0;
847
848 Bool_t result = kTRUE;
849
850 const char* type = 0;
851 TString backupURI;
852 if(gridURI == fgkMainCDB) {
853 type = "OCDB";
854 backupURI = fgkLocalCDB;
855 } else if(gridURI == fgkMainRefStorage) {
856 type = "reference";
857 backupURI = fgkLocalRefStorage;
858 } else {
859 AliError(Form("Invalid storage URI: %s", gridURI.Data()));
860 return kFALSE;
861 }
862
863 AliCDBManager* man = AliCDBManager::Instance();
864
865 AliCDBStorage *gridSto = man->GetStorage(gridURI);
866 if(!gridSto) {
867 Log(fCurrentDetector.Data(),
868 Form("TryToStoreAgain - cannot activate main %s storage", type));
869 return kFALSE;
870 }
871
872 gridIds = gridSto->GetQueryCDBList();
873
874 // get objects previously stored in local CDB
875 AliCDBStorage *backupSto = man->GetStorage(backupURI);
876 AliCDBPath aPath(fCurrentDetector,"*","*");
877 // Local objects were stored with current run as Grid version!
878 TList* localEntries = backupSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
879 localEntries->SetOwner(1);
880
881 // loop on local stored objects
882 TIter localIter(localEntries);
883 AliCDBEntry *aLocEntry = 0;
884 while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
885 aLocEntry->SetOwner(1);
886 AliCDBId aLocId = aLocEntry->GetId();
887 aLocEntry->SetVersion(-1);
888 aLocEntry->SetSubVersion(-1);
889
890 // loop on Grid valid Id's
891 Bool_t store = kTRUE;
892 TIter gridIter(gridIds);
893 AliCDBId* aGridId = 0;
894 while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
895 // If local object is valid up to infinity we store it anyway
896 // TODO This does not work! It may hide more recent objects...
897 if(aLocId.GetLastRun() == AliCDBRunRange::Infinity()) {
898 // TODO Check that it won't hide more recent files! how????
899 break;
900 }
901 if(aGridId->GetPath() != aLocId.GetPath()) continue;
902 // skip all objects valid up to infinity
903 if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
904 // if we get here, it means there's already some more recent object stored on Grid!
905 store = kFALSE;
906 break;
907 }
908
909 if(!store){
910 Log(fCurrentDetector.Data(),
911 Form("TryToStoreAgain - A more recent object already exists in %s storage: <%s>",
912 type, aGridId->ToString().Data()));
913 // removing local filename...
914 // TODO maybe it's better not to remove it, it was not copied to the Grid!
915 TString filename;
916 backupSto->IdToFilename(aLocId, filename);
917 AliInfo(Form("Removing local file %s", filename.Data()));
918 gSystem->Exec(Form("rm %s",filename.Data()));
919 continue;
920 }
921
922 // If we get here, the file can be stored!
923 Bool_t storeOk = gridSto->Put(aLocEntry);
924 if(storeOk){
925 Log(fCurrentDetector.Data(),
926 Form("TryToStoreAgain - Object <%s> successfully put into %s storage",
927 aLocId.ToString().Data(), type));
928
929 // removing local filename...
930 TString filename;
931 backupSto->IdToFilename(aLocId, filename);
932 AliInfo(Form("Removing local file %s", filename.Data()));
933 gSystem->Exec(Form("rm %s", filename.Data()));
934 continue;
935 } else {
936 Log(fCurrentDetector.Data(),
937 Form("TryToStoreAgain - Grid %s storage of object <%s> failed again",
938 type, aLocId.ToString().Data()));
939 result = kFALSE;
940 }
941 }
942 localEntries->Clear();
943
944 return result;
73abe331 945}
946
b948db8d 947//______________________________________________________________________________________________
73abe331 948Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* alias,
2bb7b766 949 TObjArray* valueSet)
73abe331 950{
58bc3020 951// Retrieve all "alias" data points from the DCS server
952// host, port: TSocket connection parameters
953// alias: name of the alias
2bb7b766 954// valueSet: array of retrieved AliDCSValue's
58bc3020 955
73abe331 956 AliDCSClient client(host, port, fTimeout, fRetries);
957 if (!client.IsConnected()) {
b948db8d 958 return kFALSE;
73abe331 959 }
960
57f50b3c 961 Int_t result = client.GetAliasValues(alias,
73abe331 962 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
963
964 if (result < 0) {
2bb7b766 965 Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get '%s'! Reason: %s",
73abe331 966 alias, AliDCSClient::GetErrorString(result)));
967
968 if (result == AliDCSClient::fgkServerError) {
2bb7b766 969 Log(fCurrentDetector.Data(), Form("GetValueSet - Server error: %s",
73abe331 970 client.GetServerError().Data()));
971 }
972
973 return kFALSE;
974 }
975
976 return kTRUE;
977}
b948db8d 978
979//______________________________________________________________________________________________
57f50b3c 980const char* AliShuttle::GetFile(Int_t system, const char* detector,
981 const char* id, const char* source)
b948db8d 982{
57f50b3c 983// Get calibration file from file exchange servers
984// calls specific getter according to system index (kDAQ, kDCS, kHLT)
985
986 switch(system){
987 case kDAQ:
988 return GetDAQFileName(detector, id, source);
989 break;
990 case kDCS:
991 return GetDCSFileName(detector, id, source);
992 break;
993 case kHLT:
994 return GetHLTFileName(detector, id, source);
995 break;
996 default:
997 AliError(Form("No valid system index: %d",system));
998 }
b948db8d 999
b948db8d 1000 return 0;
1001}
1002
b948db8d 1003//______________________________________________________________________________________________
57f50b3c 1004TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
b948db8d 1005{
57f50b3c 1006// Get sources producing the condition file Id from file exchange servers
1007// calls specific getter according to system index (kDAQ, kDCS, kHLT)
1008
1009 switch(system){
1010 case kDAQ:
1011 return GetDAQFileSources(detector, id);
1012 break;
1013 case kDCS:
1014 return GetDCSFileSources(detector, id);
1015 break;
1016 case kHLT:
1017 return GetHLTFileSources(detector, id);
1018 break;
1019 default:
1020 AliError(Form("No valid system index: %d",system));
1021 }
1022
1023 return NULL;
1024}
1025
1026//______________________________________________________________________________________________
2bb7b766 1027Bool_t AliShuttle::Connect(Int_t system)
1028{
57f50b3c 1029// Connect to MySQL Server of the system's FES logbook
2bb7b766 1030// DAQ Logbook, Shuttle Logbook and DAQ FES Logbook are on the same host
57f50b3c 1031
1032 // check connection: if already connected return
1033 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
1034
1035 TString aFESlbHost= Form("mysql://%s", fConfig->GetFESlbHost(system));
1036
1037 fServer[system] = TSQLServer::Connect(aFESlbHost,
1038 fConfig->GetFESlbUser(system),
1039 fConfig->GetFESlbPass(system));
1040 if (!fServer[system] || !fServer[system]->IsConnected()) {
2bb7b766 1041 AliError(Form("Can't establish connection to FES logbook for %s",fkSystemNames[system]));
1042 if(fServer[system]) delete fServer[system];
57f50b3c 1043 return kFALSE;
1044 }
1045
1046 // Get tables
1047 // TODO in the configuration should the table name be there too?
2bb7b766 1048 TSQLResult* aResult=0;
57f50b3c 1049 switch(system){
1050 case kDAQ:
2bb7b766 1051 aResult = fServer[kDAQ]->GetTables("REFSYSLOG");
57f50b3c 1052 break;
1053 case kDCS:
2bb7b766 1054 //aResult = fServer[kDCS]->GetTables("REFSYSLOG");
57f50b3c 1055 break;
1056 case kHLT:
2bb7b766 1057 //aResult = fServer[kHLT]->GetTables("REFSYSLOG");
57f50b3c 1058 break;
1059 default:
1060 break;
1061 }
1062
2bb7b766 1063 delete aResult;
57f50b3c 1064 return kTRUE;
1065}
1066
1067//______________________________________________________________________________________________
2bb7b766 1068const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source)
1069{
57f50b3c 1070// Retrieves a file from the DAQ FES.
1071// First queris the DAQ logbook_fs for the DAQ file name, using the run, detector, id and source info
1072// then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
2bb7b766 1073// run: current run being processed (given by Logbook entry fLogbookEntry)
57f50b3c 1074// detector: comes from the Preprocessor name (must be converted into detector code with GetDetCode)
1075// id: provided as a parameter by the Preprocessor
1076// source: provided by the Preprocessor through GetFileSources function
1077
1078 // check connection, in case connect
1079 if(!Connect(kDAQ)){
2bb7b766 1080 Log(detector, "GetDAQFileName - Couldn't connect to DAQ Logbook");
57f50b3c 1081 return 0;
1082 }
1083
1084 // Query preparation
1085 TString sqlQueryStart = "select filePath from logbook_fs where";
1086 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
2bb7b766 1087 GetCurrentRun(), GetDetCode(detector), id, source);
57f50b3c 1088 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1089
84090f85 1090 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 1091
1092 // Query execution
2bb7b766 1093 TSQLResult* aResult = 0;
1094 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
57f50b3c 1095 if (!aResult) {
2bb7b766 1096 Log(detector, Form("GetDAQFileName - Can't execute SQL query for: id = %s, source = %s",
1097 id, source));
57f50b3c 1098 return 0;
1099 }
1100
1101 if (aResult->GetRowCount() == 0) {
1102 Log(detector,
2bb7b766 1103 Form("GetDAQFileName - No entry in FES table for: id = %s, source = %s",
1104 id, source));
57f50b3c 1105 delete aResult;
1106 return 0;
1107 }
1108
1109 if (aResult->GetRowCount() >1) {
1110 Log(detector,
2bb7b766 1111 Form("GetDAQFileName - More than one entry in FES table for: id = %s, source = %s",
1112 id, source));
57f50b3c 1113 delete aResult;
1114 return 0;
1115 }
1116
2bb7b766 1117 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
57f50b3c 1118
1119 if(!aRow){
2bb7b766 1120 Log(detector, Form("GetDAQFileName - Empty set result from query: id = %s, source = %s",
1121 id, source));
57f50b3c 1122 delete aResult;
1123 return 0;
1124 }
1125
1126 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
1127
1128 delete aResult;
2bb7b766 1129 delete aRow;
57f50b3c 1130
84090f85 1131 AliDebug(2, Form("filePath = %s",filePath.Data()));
57f50b3c 1132
1133 // retrieved file is renamed to make it unique
1134 TString localFileName = Form("%s_%d_%s_%s.shuttle",
2bb7b766 1135 detector, GetCurrentRun(), id, source);
57f50b3c 1136
1137 // file retrieval from DAQ FES
1138 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
1139 if(!result) {
2bb7b766 1140 Log(detector, Form("GetDAQFileName - Copy of file %s from DAQ FES failed", filePath.Data()));
57f50b3c 1141 return 0;
1142 } else {
2bb7b766 1143 AliInfo(Form("File %s copied from DAQ FES into %s/%s",
57f50b3c 1144 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
1145 }
1146
1147
1148 fFESCalled[kDAQ]=kTRUE;
1149 TObjString *fileParams = new TObjString(Form("%s_!?!_%s", id, source));
1150 fFESlist[kDAQ].Add(fileParams);
1151
1152 return localFileName.Data();
1153
1154}
1155
1156//______________________________________________________________________________________________
2bb7b766 1157Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName)
1158{
57f50b3c 1159
1160 // check temp directory: trying to cd to temp; if it does not exist, create it
84090f85 1161 AliDebug(2, Form("Copy file %s from DAQ FES into folder %s and rename it as %s",
57f50b3c 1162 daqFileName,fgkShuttleTempDir, localFileName));
1163
1164 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
1165 if (dir == NULL) {
1166 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
2bb7b766 1167 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
57f50b3c 1168 return kFALSE;
1169 }
1170
1171 } else {
1172 gSystem->FreeDirectory(dir);
1173 }
1174
1175 TString baseDAQFESFolder = "DAQ";
1176 TString command = Form("scp %s@%s:%s/%s %s/%s",
1177 fConfig->GetFESUser(kDAQ),
1178 fConfig->GetFESHost(kDAQ),
1179 baseDAQFESFolder.Data(),
1180 daqFileName,
1181 fgkShuttleTempDir,
1182 localFileName);
1183
84090f85 1184 AliDebug(2, Form("%s",command.Data()));
57f50b3c 1185
1186 UInt_t nRetries = 0;
1187 UInt_t maxRetries = 3;
1188
1189 // copy!! if successful TSystem::Exec returns 0
1190 while(nRetries++ < maxRetries) {
84090f85 1191 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
57f50b3c 1192 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
1193 }
1194
1195 return kFALSE;
1196
1197}
1198
1199//______________________________________________________________________________________________
2bb7b766 1200TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id)
1201{
57f50b3c 1202// Retrieves a file from the DCS FES.
1203
1204 // check connection, in case connect
1205 if(!Connect(kDAQ)){
2bb7b766 1206 Log(detector, "GetDAQFileSources - Couldn't connect to DAQ Logbook");
57f50b3c 1207 return 0;
1208 }
1209
1210 // Query preparation
1211 TString sqlQueryStart = "select DAQsource from logbook_fs where";
1212 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
2bb7b766 1213 GetCurrentRun(), GetDetCode(detector), id);
57f50b3c 1214 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1215
84090f85 1216 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 1217
1218 // Query execution
1219 TSQLResult* aResult;
1220 aResult = fServer[kDAQ]->Query(sqlQuery);
1221 if (!aResult) {
2bb7b766 1222 Log(detector, Form("GetDAQFileSources - Can't execute SQL query for id: %s", id));
57f50b3c 1223 return 0;
1224 }
1225
1226 if (aResult->GetRowCount() == 0) {
1227 Log(detector,
2bb7b766 1228 Form("GetDAQFileSources - No entry in FES table for id: %s", id));
57f50b3c 1229 delete aResult;
1230 return 0;
1231 }
1232
1233 TSQLRow* aRow;
1234 TList *list = new TList();
1235 list->SetOwner(1);
1236
1237 while((aRow = aResult->Next())){
1238
1239 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
84090f85 1240 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
57f50b3c 1241 list->Add(new TObjString(daqSource));
2bb7b766 1242 delete aRow;
57f50b3c 1243 }
1244 delete aResult;
1245
1246 return list;
1247
1248}
1249
1250//______________________________________________________________________________________________
2bb7b766 1251const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1252// Retrieves a file from the DCS FES.
1253
1254return "You're in DCS";
1255
1256}
1257
1258//______________________________________________________________________________________________
1259TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
1260// Retrieves a file from the DCS FES.
1261
1262return NULL;
1263
1264}
1265
1266//______________________________________________________________________________________________
1267const char* AliShuttle::GetHLTFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1268// Retrieves a file from the HLT FES.
1269
1270return "You're in HLT";
1271
1272}
1273
1274//______________________________________________________________________________________________
1275TList* AliShuttle::GetHLTFileSources(const char* /*detector*/, const char* /*id*/){
1276// Retrieves a file from the HLT FES.
1277
1278return NULL;
1279
1280}
1281
1282//______________________________________________________________________________________________
1283Bool_t AliShuttle::UpdateDAQTable()
1284{
57f50b3c 1285// Update DAQ table filling time_processed field in all rows corresponding to current run and detector
1286
1287 // check connection, in case connect
1288 if(!Connect(kDAQ)){
2bb7b766 1289 Log(fCurrentDetector, "UpdateDAQTable - Couldn't connect to DAQ Logbook");
57f50b3c 1290 return kFALSE;
1291 }
1292
1293 TTimeStamp now; // now
1294
1295 // Loop on FES list entries
1296 TIter iter(&fFESlist[kDAQ]);
1297 TObjString *aFESentry=0;
1298 while((aFESentry = dynamic_cast<TObjString*> (iter.Next()))){
1299 TString aFESentrystr = aFESentry->String();
1300 TObjArray *aFESarray = aFESentrystr.Tokenize("_!?!_");
1301 if(!aFESarray || aFESarray->GetEntries() != 2 ) {
2bb7b766 1302 Log(fCurrentDetector, Form("UpdateDAQTable - error updating FES entry. Check string: <%s>",
57f50b3c 1303 aFESentrystr.Data()));
1304 if(aFESarray) delete aFESarray;
1305 return kFALSE;
1306 }
1307 const char* fileId = ((TObjString*) aFESarray->At(0))->GetName();
1308 const char* daqSource = ((TObjString*) aFESarray->At(1))->GetName();
1309 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
2bb7b766 1310 GetCurrentRun(), GetDetCode(fCurrentDetector), fileId, daqSource);
57f50b3c 1311
1312 delete aFESarray;
1313
1314 TString sqlQuery = Form("update logbook_fs set time_processed=%d %s", now.GetSec(), whereClause.Data());
1315
84090f85 1316 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 1317
1318 // Query execution
1319 TSQLResult* aResult;
1320 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
1321 if (!aResult) {
2bb7b766 1322 Log(fCurrentDetector, Form("UpdateDAQTable - Can't execute SQL query <%s>", sqlQuery.Data()));
57f50b3c 1323 return kFALSE;
1324 }
1325 delete aResult;
2bb7b766 1326 }
57f50b3c 1327
2bb7b766 1328 return kTRUE;
1329}
57f50b3c 1330
57f50b3c 1331
2bb7b766 1332//______________________________________________________________________________________________
1333Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
1334{
1335// Update Shuttle logbook filling detector or shuttle_done column
1336// ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
57f50b3c 1337
2bb7b766 1338 // check connection, in case connect
1339 if(!Connect(kDAQ)){
1340 Log("SHUTTLE", "UpdateShuttleLogbook - Couldn't connect to DAQ Logbook.");
1341 return kFALSE;
57f50b3c 1342 }
1343
2bb7b766 1344 TString detName(detector);
1345 TString setClause;
1346 if(detName == "shuttle_done") {
1347 setClause = "set shuttle_done=1";
1348 } else {
1349 TString detCode = GetDetCode(detector);
1350 if(detCode.IsNull()) {
1351 Log("SHUTTLE", Form("UpdateShuttleLogbook - Unknown detector %s", detector));
57f50b3c 1352 return kFALSE;
1353 }
2bb7b766 1354 TString statusStr(status);
1355 if(statusStr.Contains("done", TString::kIgnoreCase) ||
1356 statusStr.Contains("failed", TString::kIgnoreCase)){
1357 setClause = Form("set %s=\"%s\"", detCode.Data(), status);
1358 } else {
1359 Log("SHUTTLE",
1360 Form("UpdateShuttleLogbook - Invalid status <%s> for detector %s",
1361 status, detector));
1362 return kFALSE;
1363 }
1364 }
57f50b3c 1365
2bb7b766 1366 TString whereClause = Form("where run=%d", GetCurrentRun());
1367
1368 TString sqlQuery = Form("update logbook_shuttle %s %s",
1369 setClause.Data(), whereClause.Data());
57f50b3c 1370
2bb7b766 1371 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1372
1373 // Query execution
1374 TSQLResult* aResult;
1375 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
1376 if (!aResult) {
1377 Log("SHUTTLE", Form("UpdateShuttleLogbook - Can't execute query <%s>", sqlQuery.Data()));
1378 return kFALSE;
57f50b3c 1379 }
2bb7b766 1380 delete aResult;
57f50b3c 1381
1382 return kTRUE;
1383}
1384
1385//______________________________________________________________________________________________
2bb7b766 1386Int_t AliShuttle::GetCurrentRun() const
1387{
1388// Get current run from logbook entry
57f50b3c 1389
2bb7b766 1390 return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
57f50b3c 1391}
1392
1393//______________________________________________________________________________________________
2bb7b766 1394UInt_t AliShuttle::GetCurrentStartTime() const
1395{
1396// get current start time
57f50b3c 1397
2bb7b766 1398 return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
57f50b3c 1399}
1400
1401//______________________________________________________________________________________________
2bb7b766 1402UInt_t AliShuttle::GetCurrentEndTime() const
1403{
1404// get current end time from logbook entry
57f50b3c 1405
2bb7b766 1406 return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
57f50b3c 1407}
1408
1409//______________________________________________________________________________________________
2bb7b766 1410const char* AliShuttle::GetDetCode(const char* detector){
1411// Return detector code
57f50b3c 1412
2bb7b766 1413 for(UInt_t iDet=0; iDet < kNDetectors; iDet++){
1414 if(!strcmp(fgkDetectorName[iDet], detector)) return fgkDetectorCode[iDet];
1415 }
57f50b3c 1416
2bb7b766 1417 AliErrorClass(Form("Unknown detector: %s",detector));
1418 return 0;
57f50b3c 1419}
1420
1421//______________________________________________________________________________________________
2bb7b766 1422const char* AliShuttle::GetDetCode(UInt_t detPos){
57f50b3c 1423// Return detector code
1424
2bb7b766 1425 if( detPos >= kNDetectors) {
1426 AliErrorClass(Form("Invalid parameter: %d", detPos));
1427 return 0;
57f50b3c 1428 }
2bb7b766 1429 return fgkDetectorCode[detPos];
1430}
b948db8d 1431
2bb7b766 1432//______________________________________________________________________________________________
1433const Int_t AliShuttle::GetDetPos(const char* detCode){
1434// Return detector position in the detector code array
1435
1436 for(UInt_t iDet=0; iDet < kNDetectors; iDet++){
1437 if(!strcmp(fgkDetectorCode[iDet], detCode)) return iDet;
1438 }
1439 return -1;
b948db8d 1440}
1441
1442//______________________________________________________________________________________________
1443void AliShuttle::Log(const char* detector, const char* message)
1444{
58bc3020 1445// Fill log string with a message
b948db8d 1446
84090f85 1447 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1448 if (dir == NULL) {
1449 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
2bb7b766 1450 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
84090f85 1451 return;
1452 }
b948db8d 1453
84090f85 1454 } else {
1455 gSystem->FreeDirectory(dir);
1456 }
b948db8d 1457
2bb7b766 1458 TString toLog = Form("%s: %s - ", TTimeStamp(time(0)).AsString("s"), detector);
1459 if(GetCurrentRun()>=0 ) toLog += Form("run %d - ", GetCurrentRun());
1460 toLog += Form("%s", message);
1461
84090f85 1462 AliInfo(toLog.Data());
b948db8d 1463
84090f85 1464 TString fileName;
1465 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1466 gSystem->ExpandPathName(fileName);
1467
1468 ofstream logFile;
1469 logFile.open(fileName, ofstream::out | ofstream::app);
1470
1471 if (!logFile.is_open()) {
1472 AliError(Form("Could not open file %s", fileName.Data()));
1473 return;
1474 }
7bfb2090 1475
84090f85 1476 logFile << toLog.Data() << "\n";
b948db8d 1477
84090f85 1478 logFile.close();
b948db8d 1479}
2bb7b766 1480
1481
1482//______________________________________________________________________________________________
1483Bool_t AliShuttle::Collect(Int_t run)
1484{
1485 //
1486 // Collects conditions data for the given run.
1487 //
1488
1489 AliInfo(Form("Collecting conditions data for run %d", run));
1490
1491 TString whereClause("where run=");
1492 whereClause += run;
1493
1494 TObjArray dateEntries;
1495 if (!QueryShuttleLogbook(whereClause, dateEntries)) {
1496 AliError("Can't retrieve entries from Shuttle logbook!");
1497 return kFALSE;
1498 }
1499
1500 if (!dateEntries.GetEntriesFast()) {
1501 AliError(Form("Retrieval of parameters for run %d failed!", run));
1502 return kFALSE;
1503 }
1504
1505 if (dateEntries.GetEntriesFast() > 1) {
1506 AliError(Form("There is more than one entry for run <%d> in Shuttle logbook!", run));
1507 return kFALSE;
1508 }
1509
1510 if (!RetrieveConditionsData(dateEntries)) {
1511 AliError("An error occured during conditions data retrieval!");
1512 return kFALSE;
1513 }
1514
1515 return kTRUE;
1516}
1517
1518//______________________________________________________________________________________________
1519Bool_t AliShuttle::CollectNew()
1520{
1521 //
1522 // Collects conditions data for all UNPROCESSED run written to DAQ LogBook.
1523 // In operational mode, this is the Shuttle function triggered by the EOR signal.
1524 //
1525
1526 Log("SHUTTLE","CollectNew - Shuttle called. Collecting conditions data for unprocessed runs");
1527
1528 TString whereClause("where shuttle_done=0");
1529
1530 TObjArray shuttleLogbookEntries;
1531 if (!QueryShuttleLogbook(whereClause, shuttleLogbookEntries)) {
1532 Log("SHUTTLE", "CollectNew - Can't retrieve entries from Shuttle logbook");
1533 return kFALSE;
1534 }
1535
1536 if (!RetrieveConditionsData(shuttleLogbookEntries)) {
1537 Log("SHUTTLE", "CollectNew - Process of at least one run failed");
1538 return kFALSE;
1539 }
1540
1541 return kTRUE;
1542}
1543
1544//______________________________________________________________________________________________
1545Bool_t AliShuttle::CollectAll()
1546{
1547 //
1548 // Collects conditions data for all runs (even if they're already done!) written in Shuttle LogBook.
1549 //
1550
1551 AliInfo("Collecting conditions data for all runs ...");
1552
1553 TObjArray dateEntries;
1554 if (!QueryShuttleLogbook("", dateEntries)) {
1555 AliError("Can't retrieve entries from Shuttle logbook");
1556 return kFALSE;
1557 }
1558
1559 if (!RetrieveConditionsData(dateEntries)) {
1560 AliError("An error occured during conditions data retrieval!");
1561 return kFALSE;
1562 }
1563
1564 return kTRUE;
1565}
1566
1567
1568//______________________________________________________________________________________________
1569Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
1570{
1571// Retrieve conditions data for all runs that aren't processed yet
1572
1573 Bool_t hasError = kFALSE;
1574
1575 TIter iter(&dateEntries);
1576 AliShuttleLogbookEntry* anEntry;
1577
1578 while ((anEntry = (AliShuttleLogbookEntry*) iter.Next())){
1579 if (!Process(anEntry)){
1580 hasError = kTRUE;
1581 }
1582 }
1583
1584 return hasError == kFALSE;
1585}