1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.13 2006/08/15 10:50:00 jgrosseo
19 effc++ corrections (alberto)
21 Revision 1.12 2006/08/08 14:19:29 jgrosseo
22 Update to shuttle classes (Alberto)
24 - Possibility to set the full object's path in the Preprocessor's and
25 Shuttle's Store functions
26 - Possibility to extend the object's run validity in the same classes
27 ("startValidity" and "validityInfinite" parameters)
28 - Implementation of the StoreReferenceData function to store reference
29 data in a dedicated CDB storage.
31 Revision 1.11 2006/07/21 07:37:20 jgrosseo
32 last run is stored after each run
34 Revision 1.10 2006/07/20 09:54:40 jgrosseo
35 introducing status management: The processing per subdetector is divided into several steps,
36 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
37 can keep track of the number of failures and skips further processing after a certain threshold is
38 exceeded. These thresholds can be configured in LDAP.
40 Revision 1.9 2006/07/19 10:09:55 jgrosseo
41 new configuration, accesst to DAQ FES (Alberto)
43 Revision 1.8 2006/07/11 12:44:36 jgrosseo
44 adding parameters for extended validity range of data produced by preprocessor
46 Revision 1.7 2006/07/10 14:37:09 jgrosseo
47 small fix + todo comment
49 Revision 1.6 2006/07/10 13:01:41 jgrosseo
50 enhanced storing of last sucessfully processed run (alberto)
52 Revision 1.5 2006/07/04 14:59:57 jgrosseo
53 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
55 Revision 1.4 2006/06/12 09:11:16 jgrosseo
56 coding conventions (Alberto)
58 Revision 1.3 2006/06/06 14:26:40 jgrosseo
59 o) removed files that were moved to STEER
60 o) shuttle updated to follow the new interface (Alberto)
62 Revision 1.2 2006/03/07 07:52:34 hristov
63 New version (B.Yordanov)
65 Revision 1.6 2005/11/19 17:19:14 byordano
66 RetrieveDATEEntries and RetrieveConditionsData added
68 Revision 1.5 2005/11/19 11:09:27 byordano
69 AliShuttle declaration added
71 Revision 1.4 2005/11/17 17:47:34 byordano
72 TList changed to TObjArray
74 Revision 1.3 2005/11/17 14:43:23 byordano
77 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
78 Initial import as subdirectory in AliRoot
80 Revision 1.2 2005/09/13 08:41:15 byordano
81 default startTime endTime added
83 Revision 1.4 2005/08/30 09:13:02 byordano
86 Revision 1.3 2005/08/29 21:15:47 byordano
92 // This class is the main manager for AliShuttle.
93 // It organizes the data retrieval from DCS and call the
94 // interface methods of AliPreprocessor.
95 // For every detector in AliShuttleConfgi (see AliShuttleConfig),
96 // data for its set of aliases is retrieved. If there is registered
97 // AliPreprocessor for this detector then it will be used
98 // accroding to the schema (see AliPreprocessor).
99 // If there isn't registered AliPreprocessor than the retrieved
100 // data is stored automatically to the undelying AliCDBStorage.
101 // For detSpec is used the alias name.
104 #include "AliShuttle.h"
106 #include "AliCDBManager.h"
107 #include "AliCDBStorage.h"
108 #include "AliCDBId.h"
109 #include "AliCDBRunRange.h"
110 #include "AliCDBPath.h"
111 #include "AliCDBEntry.h"
112 #include "AliShuttleConfig.h"
113 #include "AliDCSClient.h"
115 #include "AliPreprocessor.h"
116 #include "AliShuttleStatus.h"
121 #include <TTimeStamp.h>
122 #include <TObjString.h>
123 #include <TSQLServer.h>
124 #include <TSQLResult.h>
131 TString AliShuttle::fgkMainCDB("alien://DBFolder=ShuttleCDB");
132 TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
133 TString AliShuttle::fgkMainRefStorage("alien://DBFolder=ShuttleReference");
134 TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
136 Bool_t AliShuttle::fgkProcessDCS(kTRUE);
139 const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
140 const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
142 const char* AliShuttle::fgkDetectorName[AliShuttle::fgkNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
143 "PHOS", "CPV", "RICH", "EMCAL", "MUON_TRK", "MUON_TRG", "FMD", "ZDC", "PMD", "START", "VZERO"};
145 const char* AliShuttle::fgkDetectorCode[AliShuttle::fgkNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
146 "PHS", "CPV", "HMP", "EMC", "MCH", "MTR", "FMD", "ZDC", "PMD", "T00", "V00"};
148 //______________________________________________________________________________________________
149 AliShuttle::AliShuttle(const AliShuttleConfig* config,
150 UInt_t timeout, Int_t retries):
152 fTimeout(timeout), fRetries(retries),
155 fCurrentStartTime(0), fCurrentEndTime(0),
156 fCurrentDetector(""),
161 // config: AliShuttleConfig used
162 // timeout: timeout used for AliDCSClient connection
163 // retries: the number of retries in case of connection error.
166 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
167 for(int iSys=0;iSys<3;iSys++) {
169 fFESlist[iSys].SetOwner(kTRUE);
173 //______________________________________________________________________
174 AliShuttle::AliShuttle(const AliShuttle& /*other*/):
175 AliShuttleInterface(),
177 fTimeout(0), fRetries(0),
180 fCurrentStartTime(0), fCurrentEndTime(0),
181 fCurrentDetector(""),
185 // copy constructor (not implemented)
189 //______________________________________________________________________
190 AliShuttle &AliShuttle::operator=(const AliShuttle& /*other*/)
192 // assignment operator (not implemented)
197 //______________________________________________________________________________________________
198 AliShuttle::~AliShuttle()
202 fPreprocessorMap.DeleteAll();
203 for(int iSys=0;iSys<3;iSys++)
205 fServer[iSys]->Close();
206 delete fServer[iSys];
210 //______________________________________________________________________________________________
211 void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
214 // Registers new AliPreprocessor.
215 // It uses GetName() for indentificator of the pre processor.
216 // The pre processor is registered it there isn't any other
217 // with the same identificator (GetName()).
220 if (fPreprocessorMap.GetValue(preprocessor->GetName())) {
221 AliWarning(Form("AliPreprocessor %s is already registered!",
222 preprocessor->GetName()));
226 fPreprocessorMap.Add(new TObjString(preprocessor->GetName()), preprocessor);
229 //______________________________________________________________________________________________
230 UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
231 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
233 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
234 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
235 // using this function. Use StoreReferenceData instead!
236 // It calls WriteToCDB function which perform actual storage
238 return WriteToCDB(fgkMainCDB, fgkLocalCDB, path, object,
239 metaData, validityStart, validityInfinite);
243 //______________________________________________________________________________________________
244 UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object,
245 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
247 // Stores a CDB object in the storage for reference data. This objects will not be available during
248 // offline reconstrunction. Use this function for reference data only!
249 // It calls WriteToCDB function which perform actual storage
251 return WriteToCDB(fgkMainRefStorage, fgkLocalRefStorage, path, object,
252 metaData, validityStart, validityInfinite);
256 //______________________________________________________________________________________________
257 UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
258 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
259 Int_t validityStart, Bool_t validityInfinite)
261 // write object into the CDB. Parameters are passed by Store and StoreReferenceData functions.
262 // The parameters are:
263 // 1) Uri of the main storage (Grid)
264 // 2) Uri of the backup storage (Local)
265 // 3) the object's path.
266 // 4) the object to be stored
267 // 5) the metaData to be associated with the object
268 // 6) the validity start run number w.r.t. the current run,
269 // if the data is valid only for this run leave the default 0
270 // 7) specifies if the calibration data is valid for infinity (this means until updated),
271 // typical for calibration runs, the default is kFALSE
274 // 1 if stored in main (Grid) storage
275 // 2 if stored in backup (Local) storage
277 const char* cdbType = (mainUri == fgkMainCDB) ? "CDB" : "Reference";
279 Int_t firstRun = GetCurrentRun() - validityStart;
281 AliError("First valid run happens to be less than 0! Setting it to 0...");
286 if(validityInfinite) {
287 lastRun = AliCDBRunRange::Infinity();
289 lastRun = GetCurrentRun();
292 AliCDBId id(path, firstRun, lastRun);
296 if (!(AliCDBManager::Instance()->GetStorage(mainUri))) {
297 Log(fCurrentDetector, Form("Cannot activate main %s storage!", cdbType));
299 result = (UInt_t) AliCDBManager::Instance()->GetStorage(mainUri)
300 ->Put(object, id, metaData);
305 Log(fCurrentDetector,
306 Form("Problem with main %s storage. Object will go to local storage!", cdbType));
308 result = AliCDBManager::Instance()->GetStorage(localUri)
309 ->Put(object, id, metaData);
315 Log(fCurrentDetector, "Can't store data!");
322 //______________________________________________________________________________________________
323 AliShuttleStatus* AliShuttle::ReadShuttleStatus()
325 // Reads the AliShuttleStatus from the CDB
333 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
334 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), fCurrentRun);
339 TObject* anObject = fStatusEntry->GetObject();
340 if (anObject == NULL || anObject->IsA() != AliShuttleStatus::Class())
342 AliError("Invalid object stored to CDB!");
346 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (anObject);
350 //______________________________________________________________________________________________
351 Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
353 // writes the status for one subdetector
361 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), fCurrentRun, fCurrentRun);
363 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
365 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
369 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), fCurrentRun));
376 //______________________________________________________________________________________________
377 void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
379 // changes the AliShuttleStatus for the given detector and run to the given status
383 AliError("UNEXPECTED: fStatusEntry empty");
387 TObject* anObject = fStatusEntry->GetObject();
388 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (anObject);
392 AliError("UNEXPECTED: status could not be read from current CDB entry");
396 Log("SHUTTLE", Form("%s: Changing state from %s to %s", fCurrentDetector.Data(),
397 status->GetStatusName(), status->GetStatusName(newStatus)));
399 status->SetStatus(newStatus);
401 status->IncreaseCount();
403 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
406 //______________________________________________________________________________________________
407 Bool_t AliShuttle::ContinueProcessing()
409 // this function reads the AliShuttleStatus information from CDB and
410 // checks if the processing should be continued
411 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
413 AliShuttleStatus* status = ReadShuttleStatus();
418 Log("SHUTTLE", Form("%s: Processing first time.", fCurrentDetector.Data()));
419 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
420 return WriteShuttleStatus(status);
423 if (status->GetStatus() == AliShuttleStatus::kDone)
425 Log("SHUTTLE", Form("%s already done for run %d", fCurrentDetector.Data(), fCurrentRun));
429 if (status->GetStatus() == AliShuttleStatus::kFailed)
431 Log("SHUTTLE", Form("%s already in failed state for run %d", fCurrentDetector.Data(), fCurrentRun));
435 // TODO what to do in case of storage error? currently it does not do anything
436 if (status->GetStatus() == AliShuttleStatus::kStoreFailed)
438 Log("SHUTTLE", Form("%s: Grid storage failed at least once for run %d", fCurrentDetector.Data(), fCurrentRun));
442 // if we get here, there is a restart
445 if (status->GetStatus() == AliShuttleStatus::kPPStarted && status->GetCount() >= fConfig->GetMaxPPRetries() ||
446 status->GetCount() >= fConfig->GetMaxRetries())
448 Log("SHUTTLE", Form("%s, run %d failed too often, %d times, status %s. Skipping processing.",
449 fCurrentDetector.Data(), fCurrentRun, status->GetCount(), status->GetStatusName()));
454 Log("SHUTTLE", Form("Restart of %s, run %d. Got stuck before in %s, count %d",
455 fCurrentDetector.Data(), fCurrentRun, status->GetStatusName(), status->GetCount()));
457 UpdateShuttleStatus(AliShuttleStatus::kStarted, kTRUE);
462 //______________________________________________________________________________________________
463 Bool_t AliShuttle::Process(Int_t run, UInt_t startTime, UInt_t endTime)
466 // Makes data retrieval for all detectors in the configuration.
467 // run: is the run number used
468 // startTime: is the run start time
469 // endTime: is the run end time
470 // Returns kFALSE in case of error occured and kTRUE otherwise
473 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n", run));
476 Bool_t hasError = kFALSE;
477 for(Int_t iSys=0;iSys<3;iSys++) fFESCalled[iSys]=kFALSE;
480 fCurrentStartTime = startTime;
481 fCurrentEndTime = endTime;
483 // Loop on detectors in the configuration
484 TIter iter(fConfig->GetDetectors());
485 TObjString* aDetector;
487 while ((aDetector = (TObjString*) iter.Next())) {
488 fCurrentDetector = aDetector->String();
490 Bool_t detectorError=kFALSE;
491 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
493 if (ContinueProcessing() == kFALSE) continue;
495 AliInfo(Form("\n\n \t\t\t****** %s: START ******", aDetector->GetName()));
502 AliInfo(Form("\n \t\t\t****** %s: FINISH ****** \n\n", aDetector->GetName()));
504 // Process successful: Update time_processed field in FES logbooks!
505 if(fFESCalled[kDAQ]) {
506 hasError = (UpdateDAQTable() == kFALSE);
507 fFESlist[kDAQ].Clear();
509 //if(fFESCalled[kDCS]) {
510 // hasError = UpdateDCSTable(aDetector->GetName());
511 // fFESlist[kDCS].Clear();
513 //if(fFESCalled[kHLT]) {
514 // hasError = UpdateHLTTable(aDetector->GetName());
515 // fFESlist[kHLT].Clear();
518 // UpdateShuttleStatus(AliShuttleStatus::kDone);
522 fCurrentStartTime = 0;
525 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n", run));
527 return hasError == kFALSE;
530 //______________________________________________________________________________________________
531 Bool_t AliShuttle::Process()
534 // Makes data retrieval just for one specific detector.
535 // Threre should be a configuration for this detector.
536 // run: is the run number used
537 // startTime: is the run start time
538 // endTime: is the run end time
539 // detector: detector for which the retrieval will be made
540 // Returns kFALSE in case of error occured and kTRUE otherwise
543 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), fCurrentRun));
545 if (!fConfig->HasDetector(fCurrentDetector)) {
546 Log(fCurrentDetector, "There isn't any configuration for %s !");
547 UpdateShuttleStatus(AliShuttleStatus::kFailed);
551 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
553 TString host(fConfig->GetDCSHost(fCurrentDetector));
554 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
556 TIter iter(fConfig->GetDCSAliases(fCurrentDetector));
560 Bool_t aDCSError = kFALSE;
564 while ((anAlias = (TObjString*) iter.Next())) {
566 // TODO Test only... I've added a flag that allows to
567 // exclude DCS archive DB query
569 AliInfo("Querying DCS archive DB data...");
570 aDCSError = (GetValueSet(host, port, anAlias->String(), valueSet) == 0);
572 AliInfo(Form("Skipping DCS processing. Port = %d",port));
576 aliasMap.Add(anAlias->Clone(), valueSet.Clone());
578 TString message = Form("Error while retrieving alias %s !",
580 Log(fCurrentDetector, message.Data());
588 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
592 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
594 AliPreprocessor* aPreprocessor =
595 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
598 aPreprocessor->Initialize(fCurrentRun, fCurrentStartTime, fCurrentEndTime);
599 aPPResult = aPreprocessor->Process(&aliasMap);
601 // TODO default behaviour?
602 AliInfo(Form("No Preprocessor for %s: storing TMap of DP arrays into CDB!", fCurrentDetector.Data()));
603 AliCDBMetaData metaData;
604 AliDCSValue dcsValue(fCurrentStartTime, fCurrentEndTime);
605 metaData.SetResponsible(Form("Duck, Donald"));
606 metaData.SetProperty("StartEndTime", &dcsValue);
607 metaData.SetComment("Automatically stored by Shuttle!");
608 AliCDBPath path(fCurrentDetector,"DCS","Data");
609 aPPResult = Store(path, &aliasMap, &metaData);
612 if (aPPResult == 0) { // Preprocessor error
613 UpdateShuttleStatus(AliShuttleStatus::kPPError);
614 } else if (fGridError == kFALSE) { // process and Grid storage ok!
615 UpdateShuttleStatus(AliShuttleStatus::kDone);
616 } else { // Grid storage error (process ok, but object put in local storage)
617 UpdateShuttleStatus(AliShuttleStatus::kStoreFailed);
622 return (aPPResult > 0);
625 //______________________________________________________________________________________________
626 Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* alias,
629 // Retrieve all "alias" data points from the DCS server
630 // host, port: TSocket connection parameters
631 // alias: name of the alias
632 // valueSet: array of retrieved AliDCSValue's
634 AliDCSClient client(host, port, fTimeout, fRetries);
635 if (!client.IsConnected()) {
639 Int_t result = client.GetAliasValues(alias,
640 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
643 AliError(Form("Can't get '%s'! Reason: %s",
644 alias, AliDCSClient::GetErrorString(result)));
646 if (result == AliDCSClient::fgkServerError) {
647 AliError(Form("Server error: %s",
648 client.GetServerError().Data()));
657 //______________________________________________________________________________________________
658 const char* AliShuttle::GetFile(Int_t system, const char* detector,
659 const char* id, const char* source)
661 // Get calibration file from file exchange servers
662 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
666 return GetDAQFileName(detector, id, source);
669 return GetDCSFileName(detector, id, source);
672 return GetHLTFileName(detector, id, source);
675 AliError(Form("No valid system index: %d",system));
681 //______________________________________________________________________________________________
682 TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
684 // Get sources producing the condition file Id from file exchange servers
685 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
689 return GetDAQFileSources(detector, id);
692 return GetDCSFileSources(detector, id);
695 return GetHLTFileSources(detector, id);
698 AliError(Form("No valid system index: %d",system));
704 //______________________________________________________________________________________________
705 Bool_t AliShuttle::Connect(Int_t system){
706 // Connect to MySQL Server of the system's FES logbook
708 // check connection: if already connected return
709 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
711 TString aFESlbHost= Form("mysql://%s", fConfig->GetFESlbHost(system));
713 fServer[system] = TSQLServer::Connect(aFESlbHost,
714 fConfig->GetFESlbUser(system),
715 fConfig->GetFESlbPass(system));
716 if (!fServer[system] || !fServer[system]->IsConnected()) {
717 AliError(Form("Can't establish connection to FES logbook for %s !",fkSystemNames[system]));
722 // TODO in the configuration should the table name be there too?
725 fServer[kDAQ]->GetTables("REFSYSLOG");
728 //fServer[kDCS]->GetTables("REFSYSLOG");
731 //fServer[kHLT]->GetTables("REFSYSLOG");
740 //______________________________________________________________________________________________
741 const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source){
742 // Retrieves a file from the DAQ FES.
743 // First queris the DAQ logbook_fs for the DAQ file name, using the run, detector, id and source info
744 // then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
745 // run: current run being processed (fCurrentRun)
746 // detector: comes from the Preprocessor name (must be converted into detector code with GetDetCode)
747 // id: provided as a parameter by the Preprocessor
748 // source: provided by the Preprocessor through GetFileSources function
750 // check connection, in case connect
752 Log(detector, "GetDAQFileName: Couldn't connect to DAQ Logbook !");
757 TString sqlQueryStart = "select filePath from logbook_fs where";
758 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
759 fCurrentRun, GetDetCode(detector), id, source);
760 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
762 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
766 aResult = fServer[kDAQ]->Query(sqlQuery);
768 Log(detector, Form("Can't execute query <%s>!", sqlQuery.Data()));
772 if (aResult->GetRowCount() == 0) {
774 Form("GetDAQFileName: No result from SQL query <%s>!", sqlQuery.Data()));
779 if (aResult->GetRowCount() >1) {
781 Form("GetDAQFileName: More than one row resulting from SQL query <%s>!", sqlQuery.Data()));
786 TSQLRow* aRow = aResult->Next();
789 Log(detector, Form("GetDAQFileName: Empty set result from query <%s>!", sqlQuery.Data()));
794 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
798 AliDebug(2, Form("filePath = %s",filePath.Data()));
800 // retrieved file is renamed to make it unique
801 TString localFileName = Form("%s_%d_%s_%s.shuttle",
802 detector, fCurrentRun, id, source);
804 // file retrieval from DAQ FES
805 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
807 Log(detector, Form("copying file %s from DAQ FES failed!", filePath.Data()));
810 AliInfo(Form("File %s copied from DAQ FES into %s/%s !",
811 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
815 fFESCalled[kDAQ]=kTRUE;
816 TObjString *fileParams = new TObjString(Form("%s_!?!_%s", id, source));
817 fFESlist[kDAQ].Add(fileParams);
819 return localFileName.Data();
823 //______________________________________________________________________________________________
824 Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName){
826 // check temp directory: trying to cd to temp; if it does not exist, create it
827 AliDebug(2, Form("Copy file %s from DAQ FES into folder %s and rename it as %s",
828 daqFileName,fgkShuttleTempDir, localFileName));
830 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
832 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
833 AliError(Form("Can't open directory <%s>!", fgkShuttleTempDir));
838 gSystem->FreeDirectory(dir);
841 TString baseDAQFESFolder = "DAQ";
842 TString command = Form("scp %s@%s:%s/%s %s/%s",
843 fConfig->GetFESUser(kDAQ),
844 fConfig->GetFESHost(kDAQ),
845 baseDAQFESFolder.Data(),
850 AliDebug(2, Form("%s",command.Data()));
853 UInt_t maxRetries = 3;
855 // copy!! if successful TSystem::Exec returns 0
856 while(nRetries++ < maxRetries) {
857 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
858 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
865 //______________________________________________________________________________________________
866 TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id){
867 // Retrieves a file from the DCS FES.
869 // check connection, in case connect
871 Log(detector, "GetDAQFileName: Couldn't connect to DAQ Logbook !");
876 TString sqlQueryStart = "select DAQsource from logbook_fs where";
877 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
878 fCurrentRun, GetDetCode(detector), id);
879 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
881 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
885 aResult = fServer[kDAQ]->Query(sqlQuery);
887 Log(detector, Form("GetDAQFileSources: Can't execute query <%s>!", sqlQuery.Data()));
891 if (aResult->GetRowCount() == 0) {
893 Form("GetDAQFileSources: No result from SQL query <%s>!", sqlQuery.Data()));
899 TList *list = new TList();
902 while((aRow = aResult->Next())){
904 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
905 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
906 list->Add(new TObjString(daqSource));
914 //______________________________________________________________________________________________
915 Bool_t AliShuttle::UpdateDAQTable(){
916 // Update DAQ table filling time_processed field in all rows corresponding to current run and detector
918 // check connection, in case connect
920 Log(fCurrentDetector, "UpdateDAQTable: Couldn't connect to DAQ Logbook !");
924 TTimeStamp now; // now
926 // Loop on FES list entries
927 TIter iter(&fFESlist[kDAQ]);
928 TObjString *aFESentry=0;
929 while((aFESentry = dynamic_cast<TObjString*> (iter.Next()))){
930 TString aFESentrystr = aFESentry->String();
931 TObjArray *aFESarray = aFESentrystr.Tokenize("_!?!_");
932 if(!aFESarray || aFESarray->GetEntries() != 2 ) {
933 Log(fCurrentDetector,Form("UpdateDAQTable: error updating FES entry! string = %s",
934 aFESentrystr.Data()));
935 if(aFESarray) delete aFESarray;
938 const char* fileId = ((TObjString*) aFESarray->At(0))->GetName();
939 const char* daqSource = ((TObjString*) aFESarray->At(1))->GetName();
940 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
941 fCurrentRun,GetDetCode(fCurrentDetector), fileId, daqSource);
945 TString sqlQuery = Form("update logbook_fs set time_processed=%d %s", now.GetSec(), whereClause.Data());
947 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
951 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
953 Log(fCurrentDetector, Form("UpdateDAQTable: Can't execute query <%s>!", sqlQuery.Data()));
958 // check result - TODO Is it necessary?
959 sqlQuery = Form("select time_processed from logbook_fs %s", whereClause.Data());
960 AliDebug(2, Form(" CHECK - SQL query: \n%s",sqlQuery.Data()));
962 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
964 AliWarning("Can't check result!");
968 if (aResult->GetRowCount() == 0) {
969 Log(fCurrentDetector,
970 Form("GetDAQFileName: No result from SQL query <%s>!", sqlQuery.Data()));
975 if (aResult->GetRowCount() >1) {
976 Log(fCurrentDetector,
977 Form("GetDAQFileName: More than one row resulting from SQL query <%s>!", sqlQuery.Data()));
982 TSQLRow *row = dynamic_cast<TSQLRow*> (aResult->Next());
983 TString processedTimeString(row->GetField(0), row->GetFieldLength(0));
984 Int_t processedTime = processedTimeString.Atoi();
985 if(processedTime != now.GetSec()){
986 Log(fCurrentDetector, Form("UpdateDAQTable: Update table error: processed_time=%d, now=%d !",
987 processedTime, now.GetSec()));
999 //______________________________________________________________________________________________
1000 const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1001 // Retrieves a file from the DCS FES.
1003 return "You're in DCS";
1007 //______________________________________________________________________________________________
1008 TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
1009 // Retrieves a file from the DCS FES.
1015 //______________________________________________________________________________________________
1016 const char* AliShuttle::GetHLTFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1017 // Retrieves a file from the HLT FES.
1019 return "You're in HLT";
1023 //______________________________________________________________________________________________
1024 TList* AliShuttle::GetHLTFileSources(const char* /*detector*/, const char* /*id*/){
1025 // Retrieves a file from the HLT FES.
1031 //______________________________________________________________________________________________
1032 const char* AliShuttle::GetDetCode(const char* detector){
1033 // Return detector code
1035 for(int iDet=0; iDet < fgkNDetectors; iDet++){
1036 if(!strcmp(fgkDetectorName[iDet], detector)) return fgkDetectorCode[iDet];
1042 //______________________________________________________________________________________________
1043 void AliShuttle::Log(const char* detector, const char* message)
1045 // Fill log string with a message
1047 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1049 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
1050 AliError(Form("Can't open directory <%s>!", fgkShuttleTempDir));
1055 gSystem->FreeDirectory(dir);
1058 TString toLog = Form("%s: %s, run %d - %s", TTimeStamp(time(0)).AsString("s"),
1059 detector, GetCurrentRun(), message);
1060 AliInfo(toLog.Data());
1063 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1064 gSystem->ExpandPathName(fileName);
1067 logFile.open(fileName, ofstream::out | ofstream::app);
1069 if (!logFile.is_open()) {
1070 AliError(Form("Could not open file %s", fileName.Data()));
1074 logFile << toLog.Data() << "\n";