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