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.11 2006/07/21 07:37:20 jgrosseo
19 last run is stored after each run
21 Revision 1.10 2006/07/20 09:54:40 jgrosseo
22 introducing status management: The processing per subdetector is divided into several steps,
23 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
24 can keep track of the number of failures and skips further processing after a certain threshold is
25 exceeded. These thresholds can be configured in LDAP.
27 Revision 1.9 2006/07/19 10:09:55 jgrosseo
28 new configuration, accesst to DAQ FES (Alberto)
30 Revision 1.8 2006/07/11 12:44:36 jgrosseo
31 adding parameters for extended validity range of data produced by preprocessor
33 Revision 1.7 2006/07/10 14:37:09 jgrosseo
34 small fix + todo comment
36 Revision 1.6 2006/07/10 13:01:41 jgrosseo
37 enhanced storing of last sucessfully processed run (alberto)
39 Revision 1.5 2006/07/04 14:59:57 jgrosseo
40 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
42 Revision 1.4 2006/06/12 09:11:16 jgrosseo
43 coding conventions (Alberto)
45 Revision 1.3 2006/06/06 14:26:40 jgrosseo
46 o) removed files that were moved to STEER
47 o) shuttle updated to follow the new interface (Alberto)
49 Revision 1.2 2006/03/07 07:52:34 hristov
50 New version (B.Yordanov)
52 Revision 1.6 2005/11/19 17:19:14 byordano
53 RetrieveDATEEntries and RetrieveConditionsData added
55 Revision 1.5 2005/11/19 11:09:27 byordano
56 AliShuttle declaration added
58 Revision 1.4 2005/11/17 17:47:34 byordano
59 TList changed to TObjArray
61 Revision 1.3 2005/11/17 14:43:23 byordano
64 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
65 Initial import as subdirectory in AliRoot
67 Revision 1.2 2005/09/13 08:41:15 byordano
68 default startTime endTime added
70 Revision 1.4 2005/08/30 09:13:02 byordano
73 Revision 1.3 2005/08/29 21:15:47 byordano
79 // This class is the main manager for AliShuttle.
80 // It organizes the data retrieval from DCS and call the
81 // interface methods of AliPreprocessor.
82 // For every detector in AliShuttleConfgi (see AliShuttleConfig),
83 // data for its set of aliases is retrieved. If there is registered
84 // AliPreprocessor for this detector then it will be used
85 // accroding to the schema (see AliPreprocessor).
86 // If there isn't registered AliPreprocessor than the retrieved
87 // data is stored automatically to the undelying AliCDBStorage.
88 // For detSpec is used the alias name.
91 #include "AliShuttle.h"
93 #include "AliCDBManager.h"
94 #include "AliCDBStorage.h"
96 #include "AliCDBRunRange.h"
97 #include "AliCDBPath.h"
98 #include "AliCDBEntry.h"
99 #include "AliShuttleConfig.h"
100 #include "AliDCSClient.h"
102 #include "AliPreprocessor.h"
103 #include "AliShuttleStatus.h"
108 #include <TTimeStamp.h>
109 #include <TObjString.h>
110 #include <TSQLServer.h>
111 #include <TSQLResult.h>
118 TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
119 TString AliShuttle::fgkMainRefStorage("alien://DBFolder=ShuttleReference");
120 TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
122 const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
123 const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
125 const char* AliShuttle::fgkDetectorName[AliShuttle::fgkNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
126 "PHOS", "CPV", "RICH", "EMCAL", "MUON_TRK", "MUON_TRG", "FMD", "ZDC", "PMD", "START", "VZERO"};
128 const char* AliShuttle::fgkDetectorCode[AliShuttle::fgkNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
129 "PHS", "CPV", "HMP", "EMC", "MCH", "MTR", "FMD", "ZDC", "PMD", "T00", "V00"};
131 //______________________________________________________________________________________________
132 AliShuttle::AliShuttle(const AliShuttleConfig* config,
133 UInt_t timeout, Int_t retries):
136 fRetries(retries), fCurrentRun(-1), fCurrentStartTime(0),
137 fCurrentEndTime(0), fStatusEntry(0)
140 // config: AliShuttleConfig used
141 // timeout: timeout used for AliDCSClient connection
142 // retries: the number of retries in case of connection error.
145 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
146 for(int iSys=0;iSys<3;iSys++) {
148 fFESlist[iSys].SetOwner(kTRUE);
152 //______________________________________________________________________
153 AliShuttle::AliShuttle(const AliShuttle& /*other*/):
154 AliShuttleInterface()
156 // copy constructor (not implemented)
160 //______________________________________________________________________
161 AliShuttle &AliShuttle::operator=(const AliShuttle& /*other*/)
163 // assignment operator (not implemented)
168 //______________________________________________________________________________________________
169 AliShuttle::~AliShuttle()
173 fPreprocessorMap.DeleteAll();
174 for(int iSys=0;iSys<3;iSys++)
176 fServer[iSys]->Close();
177 delete fServer[iSys];
181 //______________________________________________________________________________________________
182 void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
185 // Registers new AliPreprocessor.
186 // It uses GetName() for indentificator of the pre processor.
187 // The pre processor is registered it there isn't any other
188 // with the same identificator (GetName()).
191 if (fPreprocessorMap.GetValue(preprocessor->GetName())) {
192 AliWarning(Form("AliPreprocessor %s is already registered!",
193 preprocessor->GetName()));
197 fPreprocessorMap.Add(new TObjString(preprocessor->GetName()), preprocessor);
200 //______________________________________________________________________________________________
201 UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
202 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
204 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
205 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
206 // using this function. Use StoreReferenceData instead!
209 // The parameters are
210 // 1) the object's path.
211 // 2) the object to be stored
212 // 3) the metaData to be associated with the object
213 // 4) the validity start run number w.r.t. the current run,
214 // if the data is valid only for this run leave the default 0
215 // 5) specifies if the calibration data is valid for infinity (this means until updated),
216 // typical for calibration runs, the default is kFALSE
220 // 1 if stored in main (Grid) CDB storage
221 // 2 if stored in backup (Local) CDB storage
224 Int_t firstRun = GetCurrentRun() - validityStart;
226 AliError("First valid run happens to be less than 0! Setting it to 0...");
231 if(validityInfinite) {
232 lastRun = AliCDBRunRange::Infinity();
234 lastRun = GetCurrentRun();
237 AliCDBId id(path, firstRun, lastRun);
241 if (!(AliCDBManager::Instance()->IsDefaultStorageSet())) {
242 Log(fCurrentDetector, "No CDB storage set!");
244 result = (UInt_t) AliCDBManager::Instance()->Put(object, id, metaData);
248 Log(fCurrentDetector,
249 "Error while storing object in main storage: it will go to local storage!");
251 result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)
252 ->Put(object, id, metaData);
257 Log(fCurrentDetector, "Can't store data!");
264 //______________________________________________________________________________________________
265 UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object,
266 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
268 // Stores a CDB object in the storage for reference data. This objects will not be available during
269 // offline reconstrunction. Use this function for reference data only!
272 // The parameters are
273 // 1) the object's path.
274 // 2) the object to be stored
275 // 3) the metaData to be associated with the object
276 // 4) the validity start run number w.r.t. the current run,
277 // if the data is valid only for this run leave the default 0
278 // 5) specifies if the calibration data is valid for infinity (this means until updated),
279 // typical for calibration runs, the default is kFALSE
283 // 1 if stored in main (Grid) reference storage
284 // 2 if stored in backup (Local) reference storage
286 Int_t firstRun = GetCurrentRun() - validityStart;
288 AliError("First valid run happens to be less than 0! Setting it to 0...");
293 if(validityInfinite) {
294 lastRun = AliCDBRunRange::Infinity();
296 lastRun = GetCurrentRun();
299 AliCDBId id(path, firstRun, lastRun);
303 if (!(AliCDBManager::Instance()->GetStorage(fgkMainRefStorage))) {
304 Log(fCurrentDetector, "Cannot activate main reference storage!");
306 result = (UInt_t) AliCDBManager::Instance()->GetStorage(fgkMainRefStorage)
307 ->Put(object, id, metaData);
312 Log(fCurrentDetector,
313 "Error while storing object in main reference storage: it will go to local ref storage!");
315 result = AliCDBManager::Instance()->GetStorage(fgkLocalRefStorage)
316 ->Put(object, id, metaData);
321 Log(fCurrentDetector, "Can't store reference data!");
328 //______________________________________________________________________________________________
329 AliShuttleStatus* AliShuttle::ReadShuttleStatus()
331 // Reads the AliShuttleStatus from the CDB
339 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
340 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), fCurrentRun);
345 TObject* anObject = fStatusEntry->GetObject();
346 if (anObject == NULL || anObject->IsA() != AliShuttleStatus::Class())
348 AliError("Invalid object stored to CDB!");
352 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (anObject);
356 //______________________________________________________________________________________________
357 Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
359 // writes the status for one subdetector
367 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), fCurrentRun, fCurrentRun);
369 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
371 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
375 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), fCurrentRun));
382 //______________________________________________________________________________________________
383 void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
385 // changes the AliShuttleStatus for the given detector and run to the given status
389 AliError("UNEXPECTED: fStatusEntry empty");
393 TObject* anObject = fStatusEntry->GetObject();
394 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (anObject);
398 AliError("UNEXPECTED: status could not be read from current CDB entry");
402 Log("SHUTTLE", Form("%s: Changing state from %s to %s", fCurrentDetector.Data(),
403 status->GetStatusName(), status->GetStatusName(newStatus)));
405 status->SetStatus(newStatus);
407 status->IncreaseCount();
409 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
412 //______________________________________________________________________________________________
413 Bool_t AliShuttle::ContinueProcessing()
415 // this function reads the AliShuttleStatus information from CDB and
416 // checks if the processing should be continued
417 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
419 AliShuttleStatus* status = ReadShuttleStatus();
424 Log("SHUTTLE", Form("%s: Processing first time.", fCurrentDetector.Data()));
425 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
426 return WriteShuttleStatus(status);
429 if (status->GetStatus() == AliShuttleStatus::kDone)
431 Log("SHUTTLE", Form("%s already done for run %d", fCurrentDetector.Data(), fCurrentRun));
435 if (status->GetStatus() == AliShuttleStatus::kFailed)
437 Log("SHUTTLE", Form("%s already in failed state for run %d", fCurrentDetector.Data(), fCurrentRun));
441 // if we get here, there is a restart
444 if (status->GetStatus() == AliShuttleStatus::kPPStarted && status->GetCount() >= fConfig->GetMaxPPRetries() ||
445 status->GetCount() >= fConfig->GetMaxRetries())
447 Log("SHUTTLE", Form("%s, run %d failed too often, %d times, status %s. Skipping processing.",
448 fCurrentDetector.Data(), fCurrentRun, status->GetCount(), status->GetStatusName()));
453 Log("SHUTTLE", Form("Restart of %s, run %d. Got stuck before in %s, count %d",
454 fCurrentDetector.Data(), fCurrentRun, status->GetStatusName(), status->GetCount()));
456 UpdateShuttleStatus(AliShuttleStatus::kStarted, kTRUE);
461 //______________________________________________________________________________________________
462 Bool_t AliShuttle::Process(Int_t run, UInt_t startTime, UInt_t endTime)
465 // Makes data retrieval for all detectors in the configuration.
466 // run: is the run number used
467 // startTime: is the run start time
468 // endTime: is the run end time
469 // Returns kFALSE in case of error occured and kTRUE otherwise
472 AliInfo(Form("\n\n ^*^*^*^*^*^* Processing run %d ^*^*^*^*^*^*", run));
475 Bool_t hasError = kFALSE;
476 for(Int_t iSys=0;iSys<3;iSys++) fFESCalled[iSys]=kFALSE;
479 fCurrentStartTime = startTime;
480 fCurrentEndTime = endTime;
482 // Loop on detectors in the configuration
483 TIter iter(fConfig->GetDetectors());
484 TObjString* aDetector;
486 while ((aDetector = (TObjString*) iter.Next())) {
487 fCurrentDetector = aDetector->String();
489 Bool_t detectorError=kFALSE;
490 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
492 if (ContinueProcessing() == kFALSE) continue;
499 AliInfo(Form("Process ended successfully for detector %s!",aDetector->GetName()));
501 // Process successful: Update time_processed field in FES logbooks!
502 if(fFESCalled[kDAQ]) {
503 hasError = (UpdateDAQTable() == kFALSE);
504 fFESlist[kDAQ].Clear();
506 //if(fFESCalled[kDCS]) {
507 // hasError = UpdateDCSTable(aDetector->GetName());
508 // fFESlist[kDCS].Clear();
510 //if(fFESCalled[kHLT]) {
511 // hasError = UpdateHLTTable(aDetector->GetName());
512 // fFESlist[kHLT].Clear();
515 UpdateShuttleStatus(AliShuttleStatus::kDone);
519 fCurrentStartTime = 0;
522 return hasError == kFALSE;
525 //______________________________________________________________________________________________
526 Bool_t AliShuttle::Process()
529 // Makes data retrieval just for one specific detector.
530 // Threre should be a configuration for this detector.
531 // run: is the run number used
532 // startTime: is the run start time
533 // endTime: is the run end time
534 // detector: detector for which the retrieval will be made
535 // Returns kFALSE in case of error occured and kTRUE otherwise
538 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), fCurrentRun));
540 if (!fConfig->HasDetector(fCurrentDetector)) {
541 Log(fCurrentDetector, "There isn't any configuration for %s !");
542 UpdateShuttleStatus(AliShuttleStatus::kFailed);
546 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
548 TString host(fConfig->GetDCSHost(fCurrentDetector));
549 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
551 TIter iter(fConfig->GetDCSAliases(fCurrentDetector));
555 Bool_t hasError = kFALSE;
556 Bool_t result=kFALSE;
558 while ((anAlias = (TObjString*) iter.Next())) {
560 //result = GetValueSet(host, port, anAlias->String(), valueSet);
561 AliInfo(Form("Port = %d",port));
564 aliasMap.Add(anAlias->Clone(), valueSet.Clone());
566 TString message = Form("Error while retrieving alias %s !",
568 Log(fCurrentDetector, message.Data());
576 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
580 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
582 AliPreprocessor* aPreprocessor =
583 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
586 aPreprocessor->Initialize(fCurrentRun, fCurrentStartTime, fCurrentEndTime);
587 hasError = (aPreprocessor->Process(&aliasMap) == 0);
589 // TODO default behaviour?
590 AliInfo(Form("No Preprocessor for %s: storing TMap of DP arrays into CDB!", fCurrentDetector.Data()));
591 AliCDBMetaData metaData;
592 AliDCSValue dcsValue(fCurrentStartTime, fCurrentEndTime);
593 metaData.SetResponsible(Form("Duck, Donald"));
594 metaData.SetProperty("StartEndTime", &dcsValue);
595 metaData.SetComment("Automatically stored by Shuttle!");
596 AliCDBPath path(fCurrentDetector,"DCS","Data");
597 hasError = (Store(path, &aliasMap, &metaData) == 0);
601 UpdateShuttleStatus(AliShuttleStatus::kPPError);
603 UpdateShuttleStatus(AliShuttleStatus::kPPDone);
607 return hasError == kFALSE;
610 //______________________________________________________________________________________________
611 Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* alias,
614 // Retrieve all "alias" data points from the DCS server
615 // host, port: TSocket connection parameters
616 // alias: name of the alias
617 // valueSet: array of retrieved AliDCSValue's
619 AliDCSClient client(host, port, fTimeout, fRetries);
620 if (!client.IsConnected()) {
624 Int_t result = client.GetAliasValues(alias,
625 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
628 AliError(Form("Can't get '%s'! Reason: %s",
629 alias, AliDCSClient::GetErrorString(result)));
631 if (result == AliDCSClient::fgkServerError) {
632 AliError(Form("Server error: %s",
633 client.GetServerError().Data()));
642 //______________________________________________________________________________________________
643 const char* AliShuttle::GetFile(Int_t system, const char* detector,
644 const char* id, const char* source)
646 // Get calibration file from file exchange servers
647 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
651 return GetDAQFileName(detector, id, source);
654 return GetDCSFileName(detector, id, source);
657 return GetHLTFileName(detector, id, source);
660 AliError(Form("No valid system index: %d",system));
666 //______________________________________________________________________________________________
667 TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
669 // Get sources producing the condition file Id from file exchange servers
670 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
674 return GetDAQFileSources(detector, id);
677 return GetDCSFileSources(detector, id);
680 return GetHLTFileSources(detector, id);
683 AliError(Form("No valid system index: %d",system));
689 //______________________________________________________________________________________________
690 Bool_t AliShuttle::Connect(Int_t system){
691 // Connect to MySQL Server of the system's FES logbook
693 // check connection: if already connected return
694 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
696 TString aFESlbHost= Form("mysql://%s", fConfig->GetFESlbHost(system));
698 fServer[system] = TSQLServer::Connect(aFESlbHost,
699 fConfig->GetFESlbUser(system),
700 fConfig->GetFESlbPass(system));
701 if (!fServer[system] || !fServer[system]->IsConnected()) {
702 AliError(Form("Can't establish connection to FES logbook for %s !",fkSystemNames[system]));
707 // TODO in the configuration should the table name be there too?
710 fServer[kDAQ]->GetTables("REFSYSLOG");
713 //fServer[kDCS]->GetTables("REFSYSLOG");
716 //fServer[kHLT]->GetTables("REFSYSLOG");
725 //______________________________________________________________________________________________
726 const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source){
727 // Retrieves a file from the DAQ FES.
728 // First queris the DAQ logbook_fs for the DAQ file name, using the run, detector, id and source info
729 // then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
730 // run: current run being processed (fCurrentRun)
731 // detector: comes from the Preprocessor name (must be converted into detector code with GetDetCode)
732 // id: provided as a parameter by the Preprocessor
733 // source: provided by the Preprocessor through GetFileSources function
735 // check connection, in case connect
737 Log(detector, "GetDAQFileName: Couldn't connect to DAQ Logbook !");
742 TString sqlQueryStart = "select filePath from logbook_fs where";
743 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
744 fCurrentRun, GetDetCode(detector), id, source);
745 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
747 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
751 aResult = fServer[kDAQ]->Query(sqlQuery);
753 Log(detector, Form("Can't execute query <%s>!", sqlQuery.Data()));
757 if (aResult->GetRowCount() == 0) {
759 Form("GetDAQFileName: No result from SQL query <%s>!", sqlQuery.Data()));
764 if (aResult->GetRowCount() >1) {
766 Form("GetDAQFileName: More than one row resulting from SQL query <%s>!", sqlQuery.Data()));
771 TSQLRow* aRow = aResult->Next();
774 Log(detector, Form("GetDAQFileName: Empty set result from query <%s>!", sqlQuery.Data()));
779 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
783 AliDebug(2, Form("filePath = %s",filePath.Data()));
785 // retrieved file is renamed to make it unique
786 TString localFileName = Form("%s_%d_%s_%s.shuttle",
787 detector, fCurrentRun, id, source);
789 // file retrieval from DAQ FES
790 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
792 Log(detector, Form("copying file %s from DAQ FES failed!", filePath.Data()));
795 AliInfo(Form("File %s copied from DAQ FES into %s/%s !",
796 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
800 fFESCalled[kDAQ]=kTRUE;
801 TObjString *fileParams = new TObjString(Form("%s_!?!_%s", id, source));
802 fFESlist[kDAQ].Add(fileParams);
804 return localFileName.Data();
808 //______________________________________________________________________________________________
809 Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName){
811 // check temp directory: trying to cd to temp; if it does not exist, create it
812 AliDebug(2, Form("Copy file %s from DAQ FES into folder %s and rename it as %s",
813 daqFileName,fgkShuttleTempDir, localFileName));
815 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
817 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
818 AliError(Form("Can't open directory <%s>!", fgkShuttleTempDir));
823 gSystem->FreeDirectory(dir);
826 TString baseDAQFESFolder = "DAQ";
827 TString command = Form("scp %s@%s:%s/%s %s/%s",
828 fConfig->GetFESUser(kDAQ),
829 fConfig->GetFESHost(kDAQ),
830 baseDAQFESFolder.Data(),
835 AliDebug(2, Form("%s",command.Data()));
838 UInt_t maxRetries = 3;
840 // copy!! if successful TSystem::Exec returns 0
841 while(nRetries++ < maxRetries) {
842 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
843 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
850 //______________________________________________________________________________________________
851 TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id){
852 // Retrieves a file from the DCS FES.
854 // check connection, in case connect
856 Log(detector, "GetDAQFileName: Couldn't connect to DAQ Logbook !");
861 TString sqlQueryStart = "select DAQsource from logbook_fs where";
862 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
863 fCurrentRun, GetDetCode(detector), id);
864 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
866 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
870 aResult = fServer[kDAQ]->Query(sqlQuery);
872 Log(detector, Form("GetDAQFileSources: Can't execute query <%s>!", sqlQuery.Data()));
876 if (aResult->GetRowCount() == 0) {
878 Form("GetDAQFileSources: No result from SQL query <%s>!", sqlQuery.Data()));
884 TList *list = new TList();
887 while((aRow = aResult->Next())){
889 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
890 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
891 list->Add(new TObjString(daqSource));
899 //______________________________________________________________________________________________
900 Bool_t AliShuttle::UpdateDAQTable(){
901 // Update DAQ table filling time_processed field in all rows corresponding to current run and detector
903 // check connection, in case connect
905 Log(fCurrentDetector, "UpdateDAQTable: Couldn't connect to DAQ Logbook !");
909 TTimeStamp now; // now
911 // Loop on FES list entries
912 TIter iter(&fFESlist[kDAQ]);
913 TObjString *aFESentry=0;
914 while((aFESentry = dynamic_cast<TObjString*> (iter.Next()))){
915 TString aFESentrystr = aFESentry->String();
916 TObjArray *aFESarray = aFESentrystr.Tokenize("_!?!_");
917 if(!aFESarray || aFESarray->GetEntries() != 2 ) {
918 Log(fCurrentDetector,Form("UpdateDAQTable: error updating FES entry! string = %s",
919 aFESentrystr.Data()));
920 if(aFESarray) delete aFESarray;
923 const char* fileId = ((TObjString*) aFESarray->At(0))->GetName();
924 const char* daqSource = ((TObjString*) aFESarray->At(1))->GetName();
925 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
926 fCurrentRun,GetDetCode(fCurrentDetector), fileId, daqSource);
930 TString sqlQuery = Form("update logbook_fs set time_processed=%d %s", now.GetSec(), whereClause.Data());
932 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
936 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
938 Log(fCurrentDetector, Form("UpdateDAQTable: Can't execute query <%s>!", sqlQuery.Data()));
943 // check result - TODO Is it necessary?
944 sqlQuery = Form("select time_processed from logbook_fs %s", whereClause.Data());
945 AliDebug(2, Form(" CHECK - SQL query: \n%s",sqlQuery.Data()));
947 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
949 AliWarning("Can't check result!");
953 if (aResult->GetRowCount() == 0) {
954 Log(fCurrentDetector,
955 Form("GetDAQFileName: No result from SQL query <%s>!", sqlQuery.Data()));
960 if (aResult->GetRowCount() >1) {
961 Log(fCurrentDetector,
962 Form("GetDAQFileName: More than one row resulting from SQL query <%s>!", sqlQuery.Data()));
967 TSQLRow *row = dynamic_cast<TSQLRow*> (aResult->Next());
968 TString processedTimeString(row->GetField(0), row->GetFieldLength(0));
969 Int_t processedTime = processedTimeString.Atoi();
970 if(processedTime != now.GetSec()){
971 Log(fCurrentDetector, Form("UpdateDAQTable: Update table error: processed_time=%d, now=%d !",
972 processedTime, now.GetSec()));
984 //______________________________________________________________________________________________
985 const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
986 // Retrieves a file from the DCS FES.
988 return "You're in DCS";
992 //______________________________________________________________________________________________
993 TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
994 // Retrieves a file from the DCS FES.
1000 //______________________________________________________________________________________________
1001 const char* AliShuttle::GetHLTFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1002 // Retrieves a file from the HLT FES.
1004 return "You're in HLT";
1008 //______________________________________________________________________________________________
1009 TList* AliShuttle::GetHLTFileSources(const char* /*detector*/, const char* /*id*/){
1010 // Retrieves a file from the HLT FES.
1016 //______________________________________________________________________________________________
1017 const char* AliShuttle::GetDetCode(const char* detector){
1018 // Return detector code
1020 for(int iDet=0; iDet < fgkNDetectors; iDet++){
1021 if(!strcmp(fgkDetectorName[iDet], detector)) return fgkDetectorCode[iDet];
1027 //______________________________________________________________________________________________
1028 void AliShuttle::Log(const char* detector, const char* message)
1030 // Fill log string with a message
1032 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1034 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
1035 AliError(Form("Can't open directory <%s>!", fgkShuttleTempDir));
1040 gSystem->FreeDirectory(dir);
1043 TString toLog = Form("%s: %s, run %d - %s", TTimeStamp(time(0)).AsString(),
1044 detector, GetCurrentRun(), message);
1045 AliInfo(toLog.Data());
1048 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1049 gSystem->ExpandPathName(fileName);
1052 logFile.open(fileName, ofstream::out | ofstream::app);
1054 if (!logFile.is_open()) {
1055 AliError(Form("Could not open file %s", fileName.Data()));
1059 logFile << toLog.Data() << "\n";