Removing warnings from the compilation
[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$
fc5a4708 18Revision 1.21 2006/12/07 08:51:26 jgrosseo
19update (alberto):
20table, db names in ldap configuration
21added GRP preprocessor
22DCS data can also be retrieved by data point
23
2c15234c 24Revision 1.20 2006/11/16 16:16:48 jgrosseo
25introducing strict run ordering flag
26removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
27
be48e3ea 28Revision 1.19 2006/11/06 14:23:04 jgrosseo
29major update (Alberto)
30o) reading of run parameters from the logbook
31o) online offline naming conversion
32o) standalone DCSclient package
33
eba76848 34Revision 1.18 2006/10/20 15:22:59 jgrosseo
35o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
36o) Merging Collect, CollectAll, CollectNew function
37o) Removing implementation of empty copy constructors (declaration still there!)
38
cb343cfd 39Revision 1.17 2006/10/05 16:20:55 jgrosseo
40adapting to new CDB classes
41
6ec0e06c 42Revision 1.16 2006/10/05 15:46:26 jgrosseo
43applying to the new interface
44
481441a2 45Revision 1.15 2006/10/02 16:38:39 jgrosseo
46update (alberto):
47fixed memory leaks
48storing of objects that failed to be stored to the grid before
49interfacing of shuttle status table in daq system
50
2bb7b766 51Revision 1.14 2006/08/29 09:16:05 jgrosseo
52small update
53
85a80aa9 54Revision 1.13 2006/08/15 10:50:00 jgrosseo
55effc++ corrections (alberto)
56
4f0ab988 57Revision 1.12 2006/08/08 14:19:29 jgrosseo
58Update to shuttle classes (Alberto)
59
60- Possibility to set the full object's path in the Preprocessor's and
61Shuttle's Store functions
62- Possibility to extend the object's run validity in the same classes
63("startValidity" and "validityInfinite" parameters)
64- Implementation of the StoreReferenceData function to store reference
65data in a dedicated CDB storage.
66
84090f85 67Revision 1.11 2006/07/21 07:37:20 jgrosseo
68last run is stored after each run
69
7bfb2090 70Revision 1.10 2006/07/20 09:54:40 jgrosseo
71introducing status management: The processing per subdetector is divided into several steps,
72after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
73can keep track of the number of failures and skips further processing after a certain threshold is
74exceeded. These thresholds can be configured in LDAP.
75
5164a766 76Revision 1.9 2006/07/19 10:09:55 jgrosseo
77new configuration, accesst to DAQ FES (Alberto)
78
57f50b3c 79Revision 1.8 2006/07/11 12:44:36 jgrosseo
80adding parameters for extended validity range of data produced by preprocessor
81
17111222 82Revision 1.7 2006/07/10 14:37:09 jgrosseo
83small fix + todo comment
84
e090413b 85Revision 1.6 2006/07/10 13:01:41 jgrosseo
86enhanced storing of last sucessfully processed run (alberto)
87
a7160fe9 88Revision 1.5 2006/07/04 14:59:57 jgrosseo
89revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
90
45a493ce 91Revision 1.4 2006/06/12 09:11:16 jgrosseo
92coding conventions (Alberto)
93
58bc3020 94Revision 1.3 2006/06/06 14:26:40 jgrosseo
95o) removed files that were moved to STEER
96o) shuttle updated to follow the new interface (Alberto)
97
b948db8d 98Revision 1.2 2006/03/07 07:52:34 hristov
99New version (B.Yordanov)
100
d477ad88 101Revision 1.6 2005/11/19 17:19:14 byordano
102RetrieveDATEEntries and RetrieveConditionsData added
103
104Revision 1.5 2005/11/19 11:09:27 byordano
105AliShuttle declaration added
106
107Revision 1.4 2005/11/17 17:47:34 byordano
108TList changed to TObjArray
109
110Revision 1.3 2005/11/17 14:43:23 byordano
111import to local CVS
112
113Revision 1.1.1.1 2005/10/28 07:33:58 hristov
114Initial import as subdirectory in AliRoot
115
73abe331 116Revision 1.2 2005/09/13 08:41:15 byordano
117default startTime endTime added
118
119Revision 1.4 2005/08/30 09:13:02 byordano
120some docs added
121
122Revision 1.3 2005/08/29 21:15:47 byordano
123some docs added
124
125*/
126
127//
128// This class is the main manager for AliShuttle.
129// It organizes the data retrieval from DCS and call the
b948db8d 130// interface methods of AliPreprocessor.
73abe331 131// For every detector in AliShuttleConfgi (see AliShuttleConfig),
132// data for its set of aliases is retrieved. If there is registered
b948db8d 133// AliPreprocessor for this detector then it will be used
134// accroding to the schema (see AliPreprocessor).
135// If there isn't registered AliPreprocessor than the retrieved
73abe331 136// data is stored automatically to the undelying AliCDBStorage.
137// For detSpec is used the alias name.
138//
139
140#include "AliShuttle.h"
141
142#include "AliCDBManager.h"
143#include "AliCDBStorage.h"
144#include "AliCDBId.h"
84090f85 145#include "AliCDBRunRange.h"
146#include "AliCDBPath.h"
5164a766 147#include "AliCDBEntry.h"
73abe331 148#include "AliShuttleConfig.h"
eba76848 149#include "DCSClient/AliDCSClient.h"
73abe331 150#include "AliLog.h"
b948db8d 151#include "AliPreprocessor.h"
5164a766 152#include "AliShuttleStatus.h"
2bb7b766 153#include "AliShuttleLogbookEntry.h"
73abe331 154
57f50b3c 155#include <TSystem.h>
58bc3020 156#include <TObject.h>
b948db8d 157#include <TString.h>
57f50b3c 158#include <TTimeStamp.h>
73abe331 159#include <TObjString.h>
57f50b3c 160#include <TSQLServer.h>
161#include <TSQLResult.h>
162#include <TSQLRow.h>
cb343cfd 163#include <TMutex.h>
73abe331 164
5164a766 165#include <fstream>
166
cb343cfd 167#include <sys/types.h>
168#include <sys/wait.h>
169
73abe331 170ClassImp(AliShuttle)
171
2bb7b766 172TString AliShuttle::fgkMainCDB("alien://folder=ShuttleCDB");
84090f85 173TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
2bb7b766 174TString AliShuttle::fgkMainRefStorage("alien://folder=ShuttleReference");
84090f85 175TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
176
4f0ab988 177Bool_t AliShuttle::fgkProcessDCS(kTRUE);
178
84090f85 179const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
180const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
57f50b3c 181
b948db8d 182//______________________________________________________________________________________________
183AliShuttle::AliShuttle(const AliShuttleConfig* config,
184 UInt_t timeout, Int_t retries):
4f0ab988 185fConfig(config),
186fTimeout(timeout), fRetries(retries),
187fPreprocessorMap(),
2bb7b766 188fLogbookEntry(0),
eba76848 189fCurrentDetector(),
85a80aa9 190fStatusEntry(0),
cb343cfd 191fGridError(kFALSE),
192fMonitoringMutex(0),
eba76848 193fLastActionTime(0),
194fLastAction()
73abe331 195{
196 //
197 // config: AliShuttleConfig used
73abe331 198 // timeout: timeout used for AliDCSClient connection
199 // retries: the number of retries in case of connection error.
200 //
201
57f50b3c 202 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
be48e3ea 203 for(int iSys=0;iSys<4;iSys++) {
57f50b3c 204 fServer[iSys]=0;
be48e3ea 205 if (iSys < 3)
2c15234c 206 fFXSlist[iSys].SetOwner(kTRUE);
57f50b3c 207 }
2bb7b766 208 fPreprocessorMap.SetOwner(kTRUE);
be48e3ea 209
210 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
211 fFirstUnprocessed[iDet] = kFALSE;
212
cb343cfd 213 fMonitoringMutex = new TMutex();
58bc3020 214}
215
b948db8d 216//______________________________________________________________________________________________
57f50b3c 217AliShuttle::~AliShuttle()
58bc3020 218{
219// destructor
220
b948db8d 221 fPreprocessorMap.DeleteAll();
be48e3ea 222 for(int iSys=0;iSys<4;iSys++)
57f50b3c 223 if(fServer[iSys]) {
224 fServer[iSys]->Close();
225 delete fServer[iSys];
eba76848 226 fServer[iSys] = 0;
57f50b3c 227 }
2bb7b766 228
229 if (fStatusEntry){
230 delete fStatusEntry;
231 fStatusEntry = 0;
232 }
cb343cfd 233
234 if (fMonitoringMutex)
235 {
236 delete fMonitoringMutex;
237 fMonitoringMutex = 0;
238 }
73abe331 239}
240
b948db8d 241//______________________________________________________________________________________________
57f50b3c 242void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
58bc3020 243{
73abe331 244 //
b948db8d 245 // Registers new AliPreprocessor.
73abe331 246 // It uses GetName() for indentificator of the pre processor.
247 // The pre processor is registered it there isn't any other
248 // with the same identificator (GetName()).
249 //
250
eba76848 251 const char* detName = preprocessor->GetName();
252 if(GetDetPos(detName) < 0)
253 AliFatal(Form("********** !!!!! Invalid detector name: %s !!!!! **********", detName));
254
255 if (fPreprocessorMap.GetValue(detName)) {
256 AliWarning(Form("AliPreprocessor %s is already registered!", detName));
73abe331 257 return;
258 }
259
eba76848 260 fPreprocessorMap.Add(new TObjString(detName), preprocessor);
73abe331 261}
b948db8d 262//______________________________________________________________________________________________
84090f85 263UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
264 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
73abe331 265{
84090f85 266 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
267 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
268 // using this function. Use StoreReferenceData instead!
85a80aa9 269 // It calls WriteToCDB function which perform actual storage
b948db8d 270
85a80aa9 271 return WriteToCDB(fgkMainCDB, fgkLocalCDB, path, object,
272 metaData, validityStart, validityInfinite);
84090f85 273
274}
275
276//______________________________________________________________________________________________
481441a2 277UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData)
84090f85 278{
279 // Stores a CDB object in the storage for reference data. This objects will not be available during
280 // offline reconstrunction. Use this function for reference data only!
85a80aa9 281 // It calls WriteToCDB function which perform actual storage
282
481441a2 283 return WriteToCDB(fgkMainRefStorage, fgkLocalRefStorage, path, object, metaData);
84090f85 284
85a80aa9 285}
286
287//______________________________________________________________________________________________
288UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
289 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
290 Int_t validityStart, Bool_t validityInfinite)
291{
292 // write object into the CDB. Parameters are passed by Store and StoreReferenceData functions.
293 // The parameters are:
294 // 1) Uri of the main storage (Grid)
295 // 2) Uri of the backup storage (Local)
296 // 3) the object's path.
297 // 4) the object to be stored
298 // 5) the metaData to be associated with the object
299 // 6) the validity start run number w.r.t. the current run,
84090f85 300 // if the data is valid only for this run leave the default 0
85a80aa9 301 // 7) specifies if the calibration data is valid for infinity (this means until updated),
84090f85 302 // typical for calibration runs, the default is kFALSE
303 //
84090f85 304 // returns 0 if fail
85a80aa9 305 // 1 if stored in main (Grid) storage
306 // 2 if stored in backup (Local) storage
84090f85 307
85a80aa9 308 const char* cdbType = (mainUri == fgkMainCDB) ? "CDB" : "Reference";
2bb7b766 309
85a80aa9 310 Int_t firstRun = GetCurrentRun() - validityStart;
84090f85 311 if(firstRun < 0) {
2bb7b766 312 AliError("First valid run happens to be less than 0! Setting it to 0.");
84090f85 313 firstRun=0;
314 }
315
316 Int_t lastRun = -1;
317 if(validityInfinite) {
318 lastRun = AliCDBRunRange::Infinity();
319 } else {
320 lastRun = GetCurrentRun();
321 }
322
2bb7b766 323 AliCDBId id(path, firstRun, lastRun, -1, -1);
324
325 if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
326 TObjString runUsed = Form("%d", GetCurrentRun());
9e080f92 327 metaData->SetProperty("RunUsed(TObjString)", runUsed.Clone());
2bb7b766 328 }
84090f85 329
330 UInt_t result = 0;
331
85a80aa9 332 if (!(AliCDBManager::Instance()->GetStorage(mainUri))) {
2bb7b766 333 AliError(Form("WriteToCDB - Cannot activate main %s storage", cdbType));
84090f85 334 } else {
85a80aa9 335 result = (UInt_t) AliCDBManager::Instance()->GetStorage(mainUri)
84090f85 336 ->Put(object, id, metaData);
337 }
338
339 if(!result) {
340
341 Log(fCurrentDetector,
2bb7b766 342 Form("WriteToCDB - Problem with main %s storage. Putting <%s> into backup storage",
343 cdbType, path.GetPath().Data()));
344
345 // Set Grid version to current run number, to ease retrieval later
346 id.SetVersion(GetCurrentRun());
84090f85 347
85a80aa9 348 result = AliCDBManager::Instance()->GetStorage(localUri)
84090f85 349 ->Put(object, id, metaData);
350
351 if(result) {
352 result = 2;
85a80aa9 353 fGridError = kTRUE;
84090f85 354 }else{
2bb7b766 355 Log(fCurrentDetector, "WriteToCDB - Can't store data!");
b948db8d 356 }
357 }
2bb7b766 358
b948db8d 359 return result;
360
73abe331 361}
362
b948db8d 363//______________________________________________________________________________________________
5164a766 364AliShuttleStatus* AliShuttle::ReadShuttleStatus()
365{
2bb7b766 366// Reads the AliShuttleStatus from the CDB
5164a766 367
2bb7b766 368 if (fStatusEntry){
369 delete fStatusEntry;
370 fStatusEntry = 0;
371 }
5164a766 372
2bb7b766 373 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
374 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
5164a766 375
2bb7b766 376 if (!fStatusEntry) return 0;
377 fStatusEntry->SetOwner(1);
5164a766 378
2bb7b766 379 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
380 if (!status) {
381 AliError("Invalid object stored to CDB!");
382 return 0;
383 }
5164a766 384
2bb7b766 385 return status;
5164a766 386}
387
388//______________________________________________________________________________________________
7bfb2090 389Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
5164a766 390{
2bb7b766 391// writes the status for one subdetector
392
393 if (fStatusEntry){
394 delete fStatusEntry;
395 fStatusEntry = 0;
396 }
5164a766 397
2bb7b766 398 Int_t run = GetCurrentRun();
5164a766 399
2bb7b766 400 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
5164a766 401
2bb7b766 402 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
403 fStatusEntry->SetOwner(1);
5164a766 404
2bb7b766 405 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
7bfb2090 406
2bb7b766 407 if (!result) {
408 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), run));
409 return kFALSE;
410 }
7bfb2090 411
2bb7b766 412 return kTRUE;
5164a766 413}
414
415//______________________________________________________________________________________________
416void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
417{
418 // changes the AliShuttleStatus for the given detector and run to the given status
419
2bb7b766 420 if (!fStatusEntry){
421 AliError("UNEXPECTED: fStatusEntry empty");
422 return;
423 }
5164a766 424
2bb7b766 425 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
5164a766 426
2bb7b766 427 if (!status){
428 AliError("UNEXPECTED: status could not be read from current CDB entry");
429 return;
430 }
5164a766 431
2c15234c 432 TString actionStr = Form("UpdateShuttleStatus - %s: Changing state from %s to %s",
eba76848 433 fCurrentDetector.Data(),
434 status->GetStatusName(),
435 status->GetStatusName(newStatus));
cb343cfd 436 Log("SHUTTLE", actionStr);
437 SetLastAction(actionStr);
5164a766 438
2bb7b766 439 status->SetStatus(newStatus);
440 if (increaseCount) status->IncreaseCount();
5164a766 441
2bb7b766 442 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
5164a766 443}
5164a766 444//______________________________________________________________________________________________
445Bool_t AliShuttle::ContinueProcessing()
446{
2bb7b766 447// this function reads the AliShuttleStatus information from CDB and
448// checks if the processing should be continued
449// if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
450
2bb7b766 451 AliShuttleLogbookEntry::Status entryStatus =
eba76848 452 fLogbookEntry->GetDetectorStatus(fCurrentDetector);
2bb7b766 453
454 if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
9e080f92 455 AliInfo(Form("ContinueProcessing - %s is %s",
2bb7b766 456 fCurrentDetector.Data(),
457 fLogbookEntry->GetDetectorStatusName(entryStatus)));
458 return kFALSE;
459 }
460
461 // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
be48e3ea 462
463 // check if current run is first unprocessed run for current detector
464 if (fConfig->StrictRunOrder(fCurrentDetector) &&
465 !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
466 {
467 Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering but this is not the first unprocessed run!"));
468 return kFALSE;
469 }
470
2bb7b766 471 AliShuttleStatus* status = ReadShuttleStatus();
472 if (!status) {
473 // first time
474 Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
475 fCurrentDetector.Data()));
476 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
477 return WriteShuttleStatus(status);
478 }
479
480 // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
481 // If it happens it may mean Logbook updating failed... let's do it now!
482 if (status->GetStatus() == AliShuttleStatus::kDone ||
483 status->GetStatus() == AliShuttleStatus::kFailed){
484 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
485 fCurrentDetector.Data(),
486 status->GetStatusName(status->GetStatus())));
487 UpdateShuttleLogbook(fCurrentDetector.Data(),
488 status->GetStatusName(status->GetStatus()));
489 return kFALSE;
490 }
491
492 if (status->GetStatus() == AliShuttleStatus::kStoreFailed) {
493 Log("SHUTTLE",
494 Form("ContinueProcessing - %s: Grid storage of one or more objects failed. Trying again now",
495 fCurrentDetector.Data()));
496 if(TryToStoreAgain()){
497 Log(fCurrentDetector.Data(), "ContinueProcessing - All objects successfully stored into OCDB");
498 UpdateShuttleStatus(AliShuttleStatus::kDone);
499 UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE");
500 } else {
501 Log("SHUTTLE",
502 Form("ContinueProcessing - %s: Grid storage failed again",
503 fCurrentDetector.Data()));
504 }
505 return kFALSE;
506 }
507
508 // if we get here, there is a restart
509
510 // abort conditions
cb343cfd 511 if (status->GetCount() >= fConfig->GetMaxRetries()) {
2bb7b766 512 Log("SHUTTLE",
513 Form("ContinueProcessing - %s failed %d times in status %s - Updating Shuttle Logbook",
514 fCurrentDetector.Data(),
515 status->GetCount(), status->GetStatusName()));
516 UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
517 return kFALSE;
518 }
519
eba76848 520 Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. Aborted before with %s. Retry number %d.",
2bb7b766 521 fCurrentDetector.Data(),
522 status->GetStatusName(), status->GetCount()));
523
cb343cfd 524 UpdateShuttleStatus(AliShuttleStatus::kStarted, kTRUE);
2bb7b766 525
526 return kTRUE;
5164a766 527}
528
529//______________________________________________________________________________________________
2bb7b766 530Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
58bc3020 531{
73abe331 532 //
b948db8d 533 // Makes data retrieval for all detectors in the configuration.
2bb7b766 534 // entry: Shuttle logbook entry, contains run paramenters and status of detectors
535 // (Unprocessed, Inactive, Failed or Done).
d477ad88 536 // Returns kFALSE in case of error occured and kTRUE otherwise
73abe331 537 //
538
2bb7b766 539 if(!entry) return kFALSE;
540
541 fLogbookEntry = entry;
542
543 if(fLogbookEntry->IsDone()){
544 Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
545 UpdateShuttleLogbook("shuttle_done");
546 fLogbookEntry = 0;
547 return kTRUE;
548 }
549
550
551 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n",
552 GetCurrentRun()));
553
eba76848 554 fLogbookEntry->Print("all");
57f50b3c 555
556 // Initialization
d477ad88 557 Bool_t hasError = kFALSE;
2c15234c 558 for(Int_t iSys=0;iSys<3;iSys++) fFXSCalled[iSys]=kFALSE;
5164a766 559
2bb7b766 560 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
561 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
562 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
563 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
d477ad88 564
57f50b3c 565 // Loop on detectors in the configuration
b948db8d 566 TIter iter(fConfig->GetDetectors());
2bb7b766 567 TObjString* aDetector = 0;
b948db8d 568
be48e3ea 569 while ((aDetector = (TObjString*) iter.Next()))
570 {
7bfb2090 571 fCurrentDetector = aDetector->String();
5164a766 572
5164a766 573 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
574
9e080f92 575 if (ContinueProcessing() == kFALSE) continue;
576
2bb7b766 577 AliPreprocessor* aPreprocessor =
578 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
be48e3ea 579 if (!aPreprocessor)
580 {
581 Log("SHUTTLE",Form("Process - %s: no preprocessor registered. Skipping",
eba76848 582 fCurrentDetector.Data()));
2bb7b766 583 continue;
584 }
585
2bb7b766 586 AliInfo(Form("\n\n \t\t\t****** run %d - %s: START ******",
587 GetCurrentRun(), aDetector->GetName()));
588
85a80aa9 589
be48e3ea 590 Int_t pid = fork();
591
592 if (pid < 0)
593 {
594 Log("SHUTTLE", "ERROR: Forking failed");
595 }
596 else if (pid > 0)
597 {
598 // parent
599 AliInfo(Form("In parent process of %d - %s: Starting monitoring",
600 GetCurrentRun(), aDetector->GetName()));
601
602 Long_t begin = time(0);
603
604 int status; // to be used with waitpid, on purpose an int (not Int_t)!
605 while (waitpid(pid, &status, WNOHANG) == 0)
606 {
607 Long_t expiredTime = time(0) - begin;
608
609 if (expiredTime > fConfig->GetPPTimeOut())
610 {
611 Log("SHUTTLE", Form("Process time out. Run time: %d seconds. Killing...",
612 expiredTime));
613
614 kill(pid, 9);
615
616 hasError = kTRUE;
617
618 gSystem->Sleep(1000);
619 }
620 else
621 {
622 if (expiredTime % 60 == 0)
623 Log("SHUTTLE", Form("Checked process. Run time: %d seconds.",
624 expiredTime));
625 gSystem->Sleep(1000);
626 }
627 }
628
629 AliInfo(Form("In parent process of %d - %s: Client has terminated.",
630 GetCurrentRun(), aDetector->GetName()));
631
632 if (WIFEXITED(status))
633 {
634 Int_t returnCode = WEXITSTATUS(status);
635
636 Log("SHUTTLE", Form("The return code is %d", returnCode));
637
638 if (returnCode != 0)
639 hasError = kTRUE;
640 }
641 }
642 else if (pid == 0)
643 {
644 // client
645 AliInfo(Form("In client process of %d - %s", GetCurrentRun(), aDetector->GetName()));
646
647 UInt_t result = ProcessCurrentDetector();
648
649 Int_t returnCode = 0; // will be set to 1 in case of an error
650
651 if (!result)
652 {
653 returnCode = 1;
654 AliInfo(Form("\n \t\t\t****** run %d - %s: PREPROCESSOR ERROR ****** \n\n",
655 GetCurrentRun(), aDetector->GetName()));
656 }
657 else if (result == 2)
658 {
659 AliInfo(Form("\n \t\t\t****** run %d - %s: STORAGE ERROR ****** \n\n",
660 GetCurrentRun(), aDetector->GetName()));
661 } else
662 {
663 AliInfo(Form("\n \t\t\t****** run %d - %s: DONE ****** \n\n",
664 GetCurrentRun(), aDetector->GetName()));
665 }
666
667 if (result > 0)
668 {
2c15234c 669 // Process successful: Update time_processed field in FXS logbooks!
670 if (fFXSCalled[kDAQ])
be48e3ea 671 {
672 if (UpdateDAQTable() == kFALSE)
673 returnCode = 1;
2c15234c 674 fFXSlist[kDAQ].Clear();
be48e3ea 675 }
2c15234c 676 //if(fFXSCalled[kDCS]) {
be48e3ea 677 // if (UpdateDCSTable(aDetector->GetName()) == kFALSE)
678 // returnCode = 1;
2c15234c 679 // fFXSlist[kDCS].Clear();
be48e3ea 680 //}
9e080f92 681 if (fFXSCalled[kHLT])
682 {
683 if (UpdateHLTTable() == kFALSE)
684 returnCode = 1;
685 fFXSlist[kHLT].Clear();
686 }
be48e3ea 687 }
688
689 AliInfo(Form("Client process of %d - %s is exiting now with %d.",
690 GetCurrentRun(), aDetector->GetName(), returnCode));
691
692 // the client exits here
693 gSystem->Exit(returnCode);
694
695 AliError("We should never get here!!!");
696 }
7bfb2090 697 }
5164a766 698
2bb7b766 699 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n",
700 GetCurrentRun()));
701
702 //check if shuttle is done for this run, if so update logbook
703 TObjArray checkEntryArray;
704 checkEntryArray.SetOwner(1);
9e080f92 705 TString whereClause = Form("where run=%d", GetCurrentRun());
706 if (!QueryShuttleLogbook(whereClause.Data(), checkEntryArray) || checkEntryArray.GetEntries() == 0) {
707 Log("SHUTTLE", Form("Process - Warning: Cannot check status of run %d on Shuttle logbook!",
708 GetCurrentRun()));
709 return hasError == kFALSE;
710 }
b948db8d 711
9e080f92 712 AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
713 (checkEntryArray.At(0));
2bb7b766 714
9e080f92 715 if (checkEntry)
716 {
717 if (checkEntry->IsDone())
be48e3ea 718 {
9e080f92 719 Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
720 UpdateShuttleLogbook("shuttle_done");
721 }
722 else
723 {
724 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
be48e3ea 725 {
9e080f92 726 if (checkEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
be48e3ea 727 {
9e080f92 728 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
729 checkEntry->GetRun(), GetDetName(iDet)));
730 fFirstUnprocessed[iDet] = kFALSE;
be48e3ea 731 }
732 }
2bb7b766 733 }
734 }
735
736 fLogbookEntry = 0;
85a80aa9 737
a7160fe9 738 return hasError == kFALSE;
73abe331 739}
740
b948db8d 741//______________________________________________________________________________________________
2bb7b766 742UInt_t AliShuttle::ProcessCurrentDetector()
73abe331 743{
744 //
2bb7b766 745 // Makes data retrieval just for a specific detector (fCurrentDetector).
73abe331 746 // Threre should be a configuration for this detector.
73abe331 747
2bb7b766 748 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), GetCurrentRun()));
73abe331 749
7bfb2090 750 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
73abe331 751
2c15234c 752 TMap dcsMap;
753 dcsMap.SetOwner(1);
73abe331 754
85a80aa9 755 Bool_t aDCSError = kFALSE;
756 fGridError = kFALSE;
d477ad88 757
2c15234c 758 // TODO Test only... I've added a flag that allows to
759 // exclude DCS archive DB query
760 if (!fgkProcessDCS)
761 {
762 AliInfo("Skipping DCS processing!");
763 aDCSError = kFALSE;
764 } else {
765 TString host(fConfig->GetDCSHost(fCurrentDetector));
766 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
767
768 // Retrieval of Aliases
769 TObjString* anAlias = 0;
770 TIter iterAliases(fConfig->GetDCSAliases(fCurrentDetector));
771 while ((anAlias = (TObjString*) iterAliases.Next()))
772 {
773 TObjArray *valueSet = new TObjArray();
774 valueSet->SetOwner(1);
775
776 AliInfo("Querying DCS archive DB (Aliases)...");
777 aDCSError = (GetValueSet(host, port, anAlias->String(), valueSet, kAlias) == 0);
778
779 if(!aDCSError)
780 {
781 dcsMap.Add(anAlias->Clone(), valueSet);
782 } else {
783 Log(fCurrentDetector,
784 Form("ProcessCurrentDetector - Error while retrieving alias %s",
785 anAlias->GetName()));
786 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
787 dcsMap.DeleteAll();
788 return 0;
789 }
4f0ab988 790 }
2c15234c 791
792 // Retrieval of Data Points
793 TObjString* aDP = 0;
794 TIter iterDP(fConfig->GetDCSDataPoints(fCurrentDetector));
795 while ((aDP = (TObjString*) iterDP.Next()))
796 {
797 TObjArray *valueSet = new TObjArray();
798 valueSet->SetOwner(1);
799 AliInfo("Querying DCS archive DB (Data Points)...");
800 aDCSError = (GetValueSet(host, port, aDP->String(), valueSet, kDP) == 0);
801
802 if(!aDCSError)
803 {
804 dcsMap.Add(aDP->Clone(), valueSet);
805 } else {
806 Log(fCurrentDetector,
807 Form("ProcessCurrentDetector - Error while retrieving data point %s",
808 aDP->GetName()));
809 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
810 dcsMap.DeleteAll();
811 return 0;
812 }
73abe331 813 }
814 }
b948db8d 815
2bb7b766 816 // DCS Archive DB processing successful. Call Preprocessor!
85a80aa9 817 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
a7160fe9 818
85a80aa9 819 AliPreprocessor* aPreprocessor =
5164a766 820 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
b948db8d 821
2bb7b766 822 aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
2c15234c 823 UInt_t aPPResult = aPreprocessor->Process(&dcsMap);
2bb7b766 824
825 UInt_t returnValue = 0;
85a80aa9 826 if (aPPResult == 0) { // Preprocessor error
cb343cfd 827 UpdateShuttleStatus(AliShuttleStatus::kPPError);
2bb7b766 828 returnValue = 0;
85a80aa9 829 } else if (fGridError == kFALSE) { // process and Grid storage ok!
830 UpdateShuttleStatus(AliShuttleStatus::kDone);
2bb7b766 831 UpdateShuttleLogbook(fCurrentDetector, "DONE");
832 Log(fCurrentDetector.Data(),
833 "ProcessCurrentDetector - Preprocessor and Grid storage ended successfully");
834 returnValue = 1;
85a80aa9 835 } else { // Grid storage error (process ok, but object put in local storage)
836 UpdateShuttleStatus(AliShuttleStatus::kStoreFailed);
2bb7b766 837 returnValue = 2;
85a80aa9 838 }
b948db8d 839
2c15234c 840 dcsMap.DeleteAll();
b948db8d 841
2bb7b766 842 return returnValue;
843}
844
845//______________________________________________________________________________________________
846Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
847 TObjArray& entries)
848{
849// Query DAQ's Shuttle logbook and fills detector status object.
850// Call QueryRunParameters to query DAQ logbook for run parameters.
851
fc5a4708 852 entries.SetOwner(1);
853
2bb7b766 854 // check connection, in case connect
be48e3ea 855 if(!Connect(3)) return kFALSE;
2bb7b766 856
857 TString sqlQuery;
858 sqlQuery = Form("select * from logbook_shuttle %s order by run", whereClause);
859
be48e3ea 860 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
2bb7b766 861 if (!aResult) {
862 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
863 return kFALSE;
864 }
865
fc5a4708 866 AliDebug(2,Form("Query = %s", sqlQuery.Data()));
867
2bb7b766 868 if(aResult->GetRowCount() == 0) {
9e080f92 869// if(sqlQuery.EndsWith("where shuttle_done=0 order by run")){
870// Log("SHUTTLE", "QueryShuttleLogbook - All runs in Shuttle Logbook are already DONE");
871// delete aResult;
872// return kTRUE;
873// } else {
874 AliInfo("No entries in Shuttle Logbook match request");
2bb7b766 875 delete aResult;
876 return kTRUE;
9e080f92 877// }
2bb7b766 878 }
879
880 // TODO Check field count!
fc5a4708 881 const UInt_t nCols = 22;
2bb7b766 882 if (aResult->GetFieldCount() != (Int_t) nCols) {
883 AliError("Invalid SQL result field number!");
884 delete aResult;
885 return kFALSE;
886 }
887
2bb7b766 888 TSQLRow* aRow;
889 while ((aRow = aResult->Next())) {
890 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
891 Int_t run = runString.Atoi();
892
eba76848 893 AliShuttleLogbookEntry *entry = QueryRunParameters(run);
894 if (!entry)
895 continue;
2bb7b766 896
897 // loop on detectors
eba76848 898 for(UInt_t ii = 0; ii < nCols; ii++)
899 entry->SetDetectorStatus(aResult->GetFieldName(ii), aRow->GetField(ii));
2bb7b766 900
eba76848 901 entries.AddLast(entry);
2bb7b766 902 delete aRow;
903 }
904
9e080f92 905// if(sqlQuery.EndsWith("where shuttle_done=0 order by run"))
906// Log("SHUTTLE", Form("QueryShuttleLogbook - Found %d unprocessed runs in Shuttle Logbook",
907// entries.GetEntriesFast()));
2bb7b766 908 delete aResult;
909 return kTRUE;
910}
911
912//______________________________________________________________________________________________
eba76848 913AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
2bb7b766 914{
eba76848 915 //
916 // Retrieve run parameters written in the DAQ logbook and sets them into AliShuttleLogbookEntry object
917 //
2bb7b766 918
919 // check connection, in case connect
be48e3ea 920 if (!Connect(3))
eba76848 921 return 0;
2bb7b766 922
923 TString sqlQuery;
2c15234c 924 sqlQuery.Form("select * from %s where run=%d", fConfig->GetDAQlbTable(), run);
2bb7b766 925
be48e3ea 926 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
2bb7b766 927 if (!aResult) {
928 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
eba76848 929 return 0;
2bb7b766 930 }
931
eba76848 932 if (aResult->GetRowCount() == 0) {
2bb7b766 933 Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
934 delete aResult;
eba76848 935 return 0;
2bb7b766 936 }
937
eba76848 938 if (aResult->GetRowCount() > 1) {
2bb7b766 939 AliError(Form("More than one entry in DAQ Logbook for run %d. Skipping", run));
940 delete aResult;
eba76848 941 return 0;
2bb7b766 942 }
943
eba76848 944 TSQLRow* aRow = aResult->Next();
945 if (!aRow)
946 {
947 AliError(Form("Could not retrieve row for run %d. Skipping", run));
948 delete aResult;
949 return 0;
950 }
2bb7b766 951
eba76848 952 AliShuttleLogbookEntry* entry = new AliShuttleLogbookEntry(run);
2bb7b766 953
eba76848 954 for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
955 entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
2bb7b766 956
eba76848 957 UInt_t startTime = entry->GetStartTime();
958 UInt_t endTime = entry->GetEndTime();
959
960 if (!startTime || !endTime || startTime > endTime) {
961 Log("SHUTTLE",
962 Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d",
963 run, startTime, endTime));
964 delete entry;
2bb7b766 965 delete aRow;
eba76848 966 delete aResult;
967 return 0;
2bb7b766 968 }
969
eba76848 970 delete aRow;
2bb7b766 971 delete aResult;
eba76848 972
973 return entry;
2bb7b766 974}
975
976//______________________________________________________________________________________________
977Bool_t AliShuttle::TryToStoreAgain()
978{
979 // Called in case the detector failed to store the object in Grid OCDB
980 // It tries to store the object again, if it does not find more recent and overlapping objects
981 // Calls underlying TryToStoreAgain(const char*) function twice, for OCDB and Reference storage.
982
983 AliInfo("Trying to store OCDB data again...");
984 Bool_t resultCDB = TryToStoreAgain(fgkMainCDB);
985
986 AliInfo("Trying to store reference data again...");
987 Bool_t resultRef = TryToStoreAgain(fgkMainRefStorage);
988
989 return resultCDB && resultRef;
990}
991
992//______________________________________________________________________________________________
993Bool_t AliShuttle::TryToStoreAgain(TString& gridURI)
994{
995 // Called by TryToStoreAgain(), performs actual storage retry
996
6ec0e06c 997 TObjArray* gridIds=0;
2bb7b766 998
999 Bool_t result = kTRUE;
1000
1001 const char* type = 0;
1002 TString backupURI;
1003 if(gridURI == fgkMainCDB) {
1004 type = "OCDB";
1005 backupURI = fgkLocalCDB;
1006 } else if(gridURI == fgkMainRefStorage) {
1007 type = "reference";
1008 backupURI = fgkLocalRefStorage;
1009 } else {
1010 AliError(Form("Invalid storage URI: %s", gridURI.Data()));
1011 return kFALSE;
1012 }
1013
1014 AliCDBManager* man = AliCDBManager::Instance();
1015
1016 AliCDBStorage *gridSto = man->GetStorage(gridURI);
1017 if(!gridSto) {
1018 Log(fCurrentDetector.Data(),
1019 Form("TryToStoreAgain - cannot activate main %s storage", type));
1020 return kFALSE;
1021 }
1022
1023 gridIds = gridSto->GetQueryCDBList();
1024
1025 // get objects previously stored in local CDB
1026 AliCDBStorage *backupSto = man->GetStorage(backupURI);
eba76848 1027 AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
2bb7b766 1028 // Local objects were stored with current run as Grid version!
1029 TList* localEntries = backupSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
1030 localEntries->SetOwner(1);
1031
1032 // loop on local stored objects
1033 TIter localIter(localEntries);
1034 AliCDBEntry *aLocEntry = 0;
1035 while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
1036 aLocEntry->SetOwner(1);
1037 AliCDBId aLocId = aLocEntry->GetId();
1038 aLocEntry->SetVersion(-1);
1039 aLocEntry->SetSubVersion(-1);
1040
1041 // loop on Grid valid Id's
1042 Bool_t store = kTRUE;
1043 TIter gridIter(gridIds);
1044 AliCDBId* aGridId = 0;
1045 while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
be48e3ea 1046 // If local object is valid up to infinity we store it only if it is
1047 // the first unprocessed run!
1048 if (aLocId.GetLastRun() == AliCDBRunRange::Infinity())
1049 {
1050 if (!fFirstUnprocessed[GetDetPos(fCurrentDetector)])
1051 {
1052 Log(fCurrentDetector.Data(),
2c15234c 1053 ("TryToStoreAgain - This object has validity infinite but "
1054 "there are previous unprocessed runs!"));
be48e3ea 1055 continue;
1056 } else {
1057 break;
1058 }
2bb7b766 1059 }
1060 if(aGridId->GetPath() != aLocId.GetPath()) continue;
1061 // skip all objects valid up to infinity
1062 if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
1063 // if we get here, it means there's already some more recent object stored on Grid!
1064 store = kFALSE;
1065 break;
1066 }
1067
1068 if(!store){
1069 Log(fCurrentDetector.Data(),
1070 Form("TryToStoreAgain - A more recent object already exists in %s storage: <%s>",
1071 type, aGridId->ToString().Data()));
1072 // removing local filename...
1073 // TODO maybe it's better not to remove it, it was not copied to the Grid!
1074 TString filename;
1075 backupSto->IdToFilename(aLocId, filename);
1076 AliInfo(Form("Removing local file %s", filename.Data()));
1077 gSystem->Exec(Form("rm %s",filename.Data()));
1078 continue;
1079 }
1080
1081 // If we get here, the file can be stored!
1082 Bool_t storeOk = gridSto->Put(aLocEntry);
1083 if(storeOk){
1084 Log(fCurrentDetector.Data(),
1085 Form("TryToStoreAgain - Object <%s> successfully put into %s storage",
1086 aLocId.ToString().Data(), type));
1087
1088 // removing local filename...
1089 TString filename;
1090 backupSto->IdToFilename(aLocId, filename);
1091 AliInfo(Form("Removing local file %s", filename.Data()));
1092 gSystem->Exec(Form("rm %s", filename.Data()));
1093 continue;
1094 } else {
1095 Log(fCurrentDetector.Data(),
1096 Form("TryToStoreAgain - Grid %s storage of object <%s> failed again",
1097 type, aLocId.ToString().Data()));
1098 result = kFALSE;
1099 }
1100 }
1101 localEntries->Clear();
1102
1103 return result;
73abe331 1104}
1105
b948db8d 1106//______________________________________________________________________________________________
2c15234c 1107Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* entry,
1108 TObjArray* valueSet, DCSType type)
73abe331 1109{
2c15234c 1110// Retrieve all "entry" data points from the DCS server
58bc3020 1111// host, port: TSocket connection parameters
2c15234c 1112// entry: name of the alias or data point
2bb7b766 1113// valueSet: array of retrieved AliDCSValue's
2c15234c 1114// type: kAlias or kDP
58bc3020 1115
73abe331 1116 AliDCSClient client(host, port, fTimeout, fRetries);
2c15234c 1117 if (!client.IsConnected())
1118 {
b948db8d 1119 return kFALSE;
73abe331 1120 }
1121
2c15234c 1122 Int_t result=0;
73abe331 1123
2c15234c 1124 if (type == kAlias)
1125 {
1126 result = client.GetAliasValues(entry,
1127 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
1128 } else
1129 if (type == kDP)
1130 {
1131 result = client.GetDPValues(entry,
1132 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
1133 }
1134
1135 if (result < 0)
1136 {
2bb7b766 1137 Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get '%s'! Reason: %s",
2c15234c 1138 entry, AliDCSClient::GetErrorString(result)));
73abe331 1139
2c15234c 1140 if (result == AliDCSClient::fgkServerError)
1141 {
2bb7b766 1142 Log(fCurrentDetector.Data(), Form("GetValueSet - Server error: %s",
73abe331 1143 client.GetServerError().Data()));
1144 }
1145
1146 return kFALSE;
1147 }
1148
1149 return kTRUE;
1150}
b948db8d 1151
1152//______________________________________________________________________________________________
57f50b3c 1153const char* AliShuttle::GetFile(Int_t system, const char* detector,
1154 const char* id, const char* source)
b948db8d 1155{
57f50b3c 1156// Get calibration file from file exchange servers
1157// calls specific getter according to system index (kDAQ, kDCS, kHLT)
1158
1159 switch(system){
1160 case kDAQ:
1161 return GetDAQFileName(detector, id, source);
1162 break;
1163 case kDCS:
1164 return GetDCSFileName(detector, id, source);
1165 break;
1166 case kHLT:
1167 return GetHLTFileName(detector, id, source);
1168 break;
1169 default:
1170 AliError(Form("No valid system index: %d",system));
1171 }
b948db8d 1172
b948db8d 1173 return 0;
1174}
1175
b948db8d 1176//______________________________________________________________________________________________
57f50b3c 1177TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
b948db8d 1178{
57f50b3c 1179// Get sources producing the condition file Id from file exchange servers
1180// calls specific getter according to system index (kDAQ, kDCS, kHLT)
1181
1182 switch(system){
1183 case kDAQ:
1184 return GetDAQFileSources(detector, id);
1185 break;
1186 case kDCS:
1187 return GetDCSFileSources(detector, id);
1188 break;
1189 case kHLT:
1190 return GetHLTFileSources(detector, id);
1191 break;
1192 default:
1193 AliError(Form("No valid system index: %d",system));
1194 }
1195
1196 return NULL;
1197}
1198
1199//______________________________________________________________________________________________
2bb7b766 1200Bool_t AliShuttle::Connect(Int_t system)
1201{
2c15234c 1202// Connect to MySQL Server of the system's FXS MySQL databases
1203// DAQ Logbook, Shuttle Logbook and DAQ FXS db are on the same host
57f50b3c 1204
1205 // check connection: if already connected return
1206 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
1207
2c15234c 1208 TString dbHost, dbUser, dbPass, dbName;
be48e3ea 1209
2c15234c 1210 if (system < 3) // FXS db servers
be48e3ea 1211 {
fc5a4708 1212 dbHost = Form("mysql://%s:%d", fConfig->GetFXSdbHost(system), fConfig->GetFXSdbPort(system));
2c15234c 1213 dbUser = fConfig->GetFXSdbUser(system);
1214 dbPass = fConfig->GetFXSdbPass(system);
1215 dbName = fConfig->GetFXSdbName(system);
be48e3ea 1216 } else { // Run & Shuttle logbook servers
1217 // TODO Will the Shuttle logbook server be the same as the Run logbook server ???
fc5a4708 1218 dbHost = Form("mysql://%s:%d", fConfig->GetDAQlbHost(), fConfig->GetDAQlbPort());
2c15234c 1219 dbUser = fConfig->GetDAQlbUser();
1220 dbPass = fConfig->GetDAQlbPass();
1221 dbName = fConfig->GetDAQlbDB();
be48e3ea 1222 }
57f50b3c 1223
2c15234c 1224 fServer[system] = TSQLServer::Connect(dbHost.Data(), dbUser.Data(), dbPass.Data());
57f50b3c 1225 if (!fServer[system] || !fServer[system]->IsConnected()) {
be48e3ea 1226 if(system < 3)
1227 {
2c15234c 1228 AliError(Form("Can't establish connection to FXS database for %s",
eba76848 1229 AliShuttleInterface::GetSystemName(system)));
be48e3ea 1230 } else {
1231 AliError("Can't establish connection to Run logbook.");
1232 }
2bb7b766 1233 if(fServer[system]) delete fServer[system];
57f50b3c 1234 return kFALSE;
1235 }
1236
1237 // Get tables
1238 // TODO in the configuration should the table name be there too?
2bb7b766 1239 TSQLResult* aResult=0;
57f50b3c 1240 switch(system){
1241 case kDAQ:
2c15234c 1242 aResult = fServer[kDAQ]->GetTables(dbName.Data());
57f50b3c 1243 break;
1244 case kDCS:
2c15234c 1245 //aResult = fServer[kDCS]->GetTables(dbName.Data());
57f50b3c 1246 break;
1247 case kHLT:
9e080f92 1248 aResult = fServer[kHLT]->GetTables(dbName.Data());
57f50b3c 1249 break;
1250 default:
2c15234c 1251 aResult = fServer[3]->GetTables(dbName.Data());
57f50b3c 1252 break;
1253 }
1254
2bb7b766 1255 delete aResult;
57f50b3c 1256 return kTRUE;
1257}
1258
1259//______________________________________________________________________________________________
2bb7b766 1260const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source)
1261{
2c15234c 1262// Retrieves a file from the DAQ FXS.
1263// First queris the DAQ FXS database for the DAQ file name, using the run, detector, id and source info
57f50b3c 1264// then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
2bb7b766 1265// run: current run being processed (given by Logbook entry fLogbookEntry)
eba76848 1266// detector: the Preprocessor name
57f50b3c 1267// id: provided as a parameter by the Preprocessor
1268// source: provided by the Preprocessor through GetFileSources function
1269
1270 // check connection, in case connect
eba76848 1271 if (!Connect(kDAQ))
1272 {
2c15234c 1273 Log(detector, "GetDAQFileName - Couldn't connect to DAQ FXS database");
57f50b3c 1274 return 0;
1275 }
1276
1277 // Query preparation
2c15234c 1278 TString sqlQueryStart = Form("select filePath from %s where", fConfig->GetFXSdbTable(kDAQ));
57f50b3c 1279 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
eba76848 1280 GetCurrentRun(), detector, id, source);
57f50b3c 1281 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1282
84090f85 1283 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 1284
1285 // Query execution
2bb7b766 1286 TSQLResult* aResult = 0;
1287 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
57f50b3c 1288 if (!aResult) {
2bb7b766 1289 Log(detector, Form("GetDAQFileName - Can't execute SQL query for: id = %s, source = %s",
1290 id, source));
57f50b3c 1291 return 0;
1292 }
1293
eba76848 1294 if(aResult->GetRowCount() == 0)
1295 {
57f50b3c 1296 Log(detector,
2c15234c 1297 Form("GetDAQFileName - No entry in FXS table for: id = %s, source = %s",
2bb7b766 1298 id, source));
57f50b3c 1299 delete aResult;
1300 return 0;
1301 }
1302
eba76848 1303 if (aResult->GetRowCount() > 1) {
57f50b3c 1304 Log(detector,
2c15234c 1305 Form("GetDAQFileName - More than one entry in FXS table for: id = %s, source = %s",
2bb7b766 1306 id, source));
57f50b3c 1307 delete aResult;
1308 return 0;
1309 }
1310
2bb7b766 1311 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
57f50b3c 1312
eba76848 1313 if (!aRow){
2bb7b766 1314 Log(detector, Form("GetDAQFileName - Empty set result from query: id = %s, source = %s",
1315 id, source));
57f50b3c 1316 delete aResult;
1317 return 0;
1318 }
1319
1320 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
1321
1322 delete aResult;
2bb7b766 1323 delete aRow;
57f50b3c 1324
84090f85 1325 AliDebug(2, Form("filePath = %s",filePath.Data()));
57f50b3c 1326
1327 // retrieved file is renamed to make it unique
9e080f92 1328 TString localFileName = Form("DAQ_%s_%d_%s_%s.shuttle",
2bb7b766 1329 detector, GetCurrentRun(), id, source);
57f50b3c 1330
2c15234c 1331 // file retrieval from DAQ FXS
57f50b3c 1332 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
1333 if(!result) {
2c15234c 1334 Log(detector, Form("GetDAQFileName - Copy of file %s from DAQ FXS failed", filePath.Data()));
57f50b3c 1335 return 0;
1336 } else {
2c15234c 1337 AliInfo(Form("File %s copied from DAQ FXS into %s/%s",
57f50b3c 1338 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
1339 }
1340
2c15234c 1341 fFXSCalled[kDAQ]=kTRUE;
9e080f92 1342 TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, source));
2c15234c 1343 fFXSlist[kDAQ].Add(fileParams);
57f50b3c 1344
9e080f92 1345 static TString fullLocalFileName;
1346 fullLocalFileName = TString::Format("%s/%s", fgkShuttleTempDir, localFileName.Data());
1347
1348 AliInfo(Form("fullLocalFileName = %s", fullLocalFileName.Data()));
1349
1350 return fullLocalFileName.Data();
57f50b3c 1351
1352}
1353
1354//______________________________________________________________________________________________
2bb7b766 1355Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName)
1356{
9e080f92 1357// Copies file from DAQ FXS to local Shuttle machine
57f50b3c 1358
1359 // check temp directory: trying to cd to temp; if it does not exist, create it
9e080f92 1360 AliDebug(2, Form("Copy file %s from DAQ FXS into %s/%s",
1361 daqFileName, fgkShuttleTempDir, localFileName));
57f50b3c 1362
1363 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
1364 if (dir == NULL) {
1365 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
2bb7b766 1366 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
57f50b3c 1367 return kFALSE;
1368 }
1369
1370 } else {
1371 gSystem->FreeDirectory(dir);
1372 }
1373
9e080f92 1374 TString baseDAQFXSFolder = "FES";
fc5a4708 1375 TString command = Form("scp -oPort=%d -2 %s@%s:%s/%s %s/%s",
1376 fConfig->GetFXSPort(kDAQ),
2c15234c 1377 fConfig->GetFXSUser(kDAQ),
1378 fConfig->GetFXSHost(kDAQ),
1379 baseDAQFXSFolder.Data(),
57f50b3c 1380 daqFileName,
1381 fgkShuttleTempDir,
1382 localFileName);
1383
84090f85 1384 AliDebug(2, Form("%s",command.Data()));
57f50b3c 1385
1386 UInt_t nRetries = 0;
1387 UInt_t maxRetries = 3;
1388
1389 // copy!! if successful TSystem::Exec returns 0
1390 while(nRetries++ < maxRetries) {
84090f85 1391 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
57f50b3c 1392 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
1393 }
1394
1395 return kFALSE;
1396
1397}
1398
1399//______________________________________________________________________________________________
2bb7b766 1400TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id)
1401{
9e080f92 1402// Retrieves list of DAQ sources of file Id
57f50b3c 1403
1404 // check connection, in case connect
1405 if(!Connect(kDAQ)){
2c15234c 1406 Log(detector, "GetDAQFileSources - Couldn't connect to DAQ FXS database");
57f50b3c 1407 return 0;
1408 }
1409
1410 // Query preparation
2c15234c 1411 TString sqlQueryStart = Form("select DAQsource from %s where", fConfig->GetFXSdbTable(kDAQ));
57f50b3c 1412 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
eba76848 1413 GetCurrentRun(), detector, id);
57f50b3c 1414 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1415
84090f85 1416 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 1417
1418 // Query execution
1419 TSQLResult* aResult;
1420 aResult = fServer[kDAQ]->Query(sqlQuery);
1421 if (!aResult) {
2bb7b766 1422 Log(detector, Form("GetDAQFileSources - Can't execute SQL query for id: %s", id));
57f50b3c 1423 return 0;
1424 }
1425
1426 if (aResult->GetRowCount() == 0) {
1427 Log(detector,
2c15234c 1428 Form("GetDAQFileSources - No entry in FXS table for id: %s", id));
57f50b3c 1429 delete aResult;
1430 return 0;
1431 }
1432
1433 TSQLRow* aRow;
1434 TList *list = new TList();
1435 list->SetOwner(1);
1436
1437 while((aRow = aResult->Next())){
1438
1439 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
84090f85 1440 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
57f50b3c 1441 list->Add(new TObjString(daqSource));
2bb7b766 1442 delete aRow;
57f50b3c 1443 }
1444 delete aResult;
1445
1446 return list;
1447
1448}
1449
1450//______________________________________________________________________________________________
2bb7b766 1451const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
2c15234c 1452// Retrieves a file from the DCS FXS.
2bb7b766 1453
1454return "You're in DCS";
1455
1456}
1457
1458//______________________________________________________________________________________________
1459TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
2c15234c 1460// Retrieves file sources from the DCS FXS.
2bb7b766 1461
1462return NULL;
1463
1464}
1465
1466//______________________________________________________________________________________________
9e080f92 1467const char* AliShuttle::GetHLTFileName(const char* detector, const char* id, const char* source){
2c15234c 1468// Retrieves a file from the HLT FXS.
9e080f92 1469// First queris the HLT FXS database for the HLT file name, using the run, detector, id and source info
1470// then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
1471// run: current run being processed (given by Logbook entry fLogbookEntry)
1472// detector: the Preprocessor name
1473// id: provided as a parameter by the Preprocessor
1474// source: provided by the Preprocessor through GetFileSources function
1475
1476 // check connection, in case connect
1477 if (!Connect(kHLT))
1478 {
1479 Log(detector, "GetHLTFileName - Couldn't connect to HLT FXS database");
1480 return 0;
1481 }
1482
1483 // Query preparation
1484 TString sqlQueryStart = Form("select filePath,fileSize,fileChecksum from %s where",
1485 fConfig->GetFXSdbTable(kHLT));
1486 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DDLnumbers=\"%s\"",
1487 GetCurrentRun(), detector, id, source);
1488 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1489
1490 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1491
1492 // Query execution
1493 TSQLResult* aResult = 0;
1494 aResult = dynamic_cast<TSQLResult*> (fServer[kHLT]->Query(sqlQuery));
1495 if (!aResult) {
1496 Log(detector, Form("GetHLTFileName - Can't execute SQL query for: id = %s, source = %s",
1497 id, source));
1498 return 0;
1499 }
1500
1501 if(aResult->GetRowCount() == 0)
1502 {
1503 Log(detector,
1504 Form("GetHLTFileName - No entry in FXS table for: id = %s, source = %s",
1505 id, source));
1506 delete aResult;
1507 return 0;
1508 }
2bb7b766 1509
9e080f92 1510 if (aResult->GetRowCount() > 1) {
1511 Log(detector,
1512 Form("GetHLTFileName - More than one entry in FXS table for: id = %s, source = %s",
1513 id, source));
1514 delete aResult;
1515 return 0;
1516 }
1517
1518 if (aResult->GetFieldCount() != 3) {
1519 Log(detector,
1520 Form("GetHLTFileName - Wrong field count in FXS table for: id = %s, source = %s",
1521 id, source));
1522 delete aResult;
1523 return 0;
1524 }
1525
1526 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
1527
1528 if (!aRow){
1529 Log(detector, Form("GetHLTFileName - Empty set result from query: id = %s, source = %s",
1530 id, source));
1531 delete aResult;
1532 return 0;
1533 }
1534
1535 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
1536 TString fileSize(aRow->GetField(1), aRow->GetFieldLength(1));
1537 TString fileMd5Sum(aRow->GetField(2), aRow->GetFieldLength(2));
1538
1539 delete aResult;
1540 delete aRow;
1541
1542 AliDebug(2, Form("filePath = %s",filePath.Data()));
1543
1544 // The full file path in HLT FXS is runNb/DET/DDLnumber/filePath
1545// TString fullFilePath = Form("%d/%s/%s/%s", GetCurrentRun(), detector, source, filePath.Data());
1546
1547 // retrieved file is renamed to make it unique
1548 TString localFileName = Form("HLT_%s_%d_%s_%s.shuttle",
1549 detector, GetCurrentRun(), id, source);
1550
1551 // file retrieval from HLT FXS
1552 Bool_t result = RetrieveHLTFile(filePath.Data(), localFileName.Data());
1553 if(!result)
1554 {
1555 Log(detector, Form("GetHLTFileName - Copy of file %s from HLT FXS failed", filePath.Data()));
1556 return 0;
1557 } else {
1558 AliInfo(Form("File %s copied from HLT FXS into %s/%s",
1559 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
1560 }
1561
1562 // compare md5sum of local file with the one stored in the HLT DB
1563 Int_t md5Comp = gSystem->Exec(Form("md5sum %s/%s |grep %s 2>&1 > /dev/null",
1564 fgkShuttleTempDir, localFileName.Data(), fileMd5Sum.Data()));
1565
1566 if (md5Comp != 0)
1567 {
1568 Log(detector, Form("GetHLTFileName - md5sum of file %s does not match with local copy!", filePath.Data()));
1569 return 0;
1570 }
1571
1572 fFXSCalled[kHLT]=kTRUE;
1573 TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, source));
1574 fFXSlist[kHLT].Add(fileParams);
1575
1576 static TString fullLocalFileName;
1577 fullLocalFileName = TString::Format("%s/%s", fgkShuttleTempDir, localFileName.Data());
1578
1579 AliInfo(Form("fullLocalFileName = %s", fullLocalFileName.Data()));
1580
1581 return fullLocalFileName.Data();
2bb7b766 1582
1583}
1584
1585//______________________________________________________________________________________________
9e080f92 1586Bool_t AliShuttle::RetrieveHLTFile(const char* hltFileName, const char* localFileName)
1587{
1588// Copies file from HLT FXS to local Shuttle machine
2bb7b766 1589
9e080f92 1590 // check temp directory: trying to cd to temp; if it does not exist, create it
1591 AliDebug(2, Form("Copy file %s from HLT FXS into %s/%s",
1592 hltFileName, fgkShuttleTempDir, localFileName));
1593
1594 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
1595 if (dir == NULL) {
1596 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
1597 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
1598 return kFALSE;
1599 }
1600
1601 } else {
1602 gSystem->FreeDirectory(dir);
1603 }
1604
1605 TString baseHLTFXSFolder = "~";
1606 TString command = Form("scp -oPort=%d %s@%s:%s/%s %s/%s",
1607 fConfig->GetFXSPort(kHLT),
1608 fConfig->GetFXSUser(kHLT),
1609 fConfig->GetFXSHost(kHLT),
1610 baseHLTFXSFolder.Data(),
1611 hltFileName,
1612 fgkShuttleTempDir,
1613 localFileName);
1614
1615 AliDebug(2, Form("%s",command.Data()));
1616
1617 UInt_t nRetries = 0;
1618 UInt_t maxRetries = 3;
1619
1620 // copy!! if successful TSystem::Exec returns 0
1621 while(nRetries++ < maxRetries) {
1622 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
1623 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
1624 }
1625
1626 return kFALSE;
1627
1628}
1629
1630//______________________________________________________________________________________________
1631TList* AliShuttle::GetHLTFileSources(const char* detector, const char* id){
1632// Retrieves list of HLT sources (DDLnumbers) of file Id
1633
1634 // check connection, in case connect
1635 if(!Connect(kHLT)){
1636 Log(detector, "GetHLTFileSources - Couldn't connect to HLT FXS database");
1637 return 0;
1638 }
1639
1640 // Query preparation
1641 TString sqlQueryStart = Form("select DDLnumbers from %s where", fConfig->GetFXSdbTable(kHLT));
1642 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
1643 GetCurrentRun(), detector, id);
1644 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1645
1646 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1647
1648 // Query execution
1649 TSQLResult* aResult;
1650 aResult = fServer[kHLT]->Query(sqlQuery);
1651 if (!aResult) {
1652 Log(detector, Form("GetHLTFileSources - Can't execute SQL query for id: %s", id));
1653 return 0;
1654 }
1655
1656 if (aResult->GetRowCount() == 0) {
1657 Log(detector,
1658 Form("GetHLTFileSources - No entry in FXS table for id: %s", id));
1659 delete aResult;
1660 return 0;
1661 }
1662
1663 TSQLRow* aRow;
1664 TList *list = new TList();
1665 list->SetOwner(1);
1666
1667 while((aRow = aResult->Next())){
1668
1669 TString ddlNumbers(aRow->GetField(0), aRow->GetFieldLength(0));
1670 AliDebug(2, Form("DDLnumbers = %s", ddlNumbers.Data()));
1671 list->Add(new TObjString(ddlNumbers));
1672 delete aRow;
1673 }
1674 delete aResult;
1675
1676 return list;
2bb7b766 1677
1678}
1679
1680//______________________________________________________________________________________________
1681Bool_t AliShuttle::UpdateDAQTable()
1682{
57f50b3c 1683// Update DAQ table filling time_processed field in all rows corresponding to current run and detector
1684
1685 // check connection, in case connect
1686 if(!Connect(kDAQ)){
2c15234c 1687 Log(fCurrentDetector, "UpdateDAQTable - Couldn't connect to DAQ FXS database");
57f50b3c 1688 return kFALSE;
1689 }
1690
1691 TTimeStamp now; // now
1692
2c15234c 1693 // Loop on FXS list entries
1694 TIter iter(&fFXSlist[kDAQ]);
1695 TObjString *aFXSentry=0;
1696 while((aFXSentry = dynamic_cast<TObjString*> (iter.Next()))){
1697 TString aFXSentrystr = aFXSentry->String();
9e080f92 1698 TObjArray *aFXSarray = aFXSentrystr.Tokenize("#!?!#");
2c15234c 1699 if(!aFXSarray || aFXSarray->GetEntries() != 2 ) {
1700 Log(fCurrentDetector, Form("UpdateDAQTable - error updating FXS entry. Check string: <%s>",
1701 aFXSentrystr.Data()));
1702 if(aFXSarray) delete aFXSarray;
57f50b3c 1703 return kFALSE;
1704 }
2c15234c 1705 const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
1706 const char* daqSource = ((TObjString*) aFXSarray->At(1))->GetName();
57f50b3c 1707 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
eba76848 1708 GetCurrentRun(), fCurrentDetector.Data(), fileId, daqSource);
57f50b3c 1709
2c15234c 1710 delete aFXSarray;
57f50b3c 1711
2c15234c 1712 TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(kDAQ),
1713 now.GetSec(), whereClause.Data());
57f50b3c 1714
84090f85 1715 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 1716
1717 // Query execution
1718 TSQLResult* aResult;
9e080f92 1719 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
57f50b3c 1720 if (!aResult) {
2bb7b766 1721 Log(fCurrentDetector, Form("UpdateDAQTable - Can't execute SQL query <%s>", sqlQuery.Data()));
57f50b3c 1722 return kFALSE;
1723 }
1724 delete aResult;
2bb7b766 1725 }
57f50b3c 1726
2bb7b766 1727 return kTRUE;
1728}
57f50b3c 1729
9e080f92 1730//______________________________________________________________________________________________
1731Bool_t AliShuttle::UpdateHLTTable()
1732{
1733// Update HLT table filling time_processed field in all rows corresponding to current run and detector
1734
1735 // check connection, in case connect
1736 if(!Connect(kHLT)){
1737 Log(fCurrentDetector, "UpdateHLTTable - Couldn't connect to HLT FXS database");
1738 return kFALSE;
1739 }
1740
1741 TTimeStamp now; // now
1742
1743 // Loop on FXS list entries
1744 TIter iter(&fFXSlist[kHLT]);
1745 TObjString *aFXSentry=0;
1746 while((aFXSentry = dynamic_cast<TObjString*> (iter.Next()))){
1747 TString aFXSentrystr = aFXSentry->String();
1748 TObjArray *aFXSarray = aFXSentrystr.Tokenize("#!?!#");
1749 if(!aFXSarray || aFXSarray->GetEntries() != 2 ) {
1750 Log(fCurrentDetector, Form("UpdateHLTTable - error updating FXS entry. Check string: <%s>",
1751 aFXSentrystr.Data()));
1752 if(aFXSarray) delete aFXSarray;
1753 return kFALSE;
1754 }
1755 const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
1756 const char* hltSource = ((TObjString*) aFXSarray->At(1))->GetName();
1757 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DDLnumbers=\"%s\";",
1758 GetCurrentRun(), fCurrentDetector.Data(), fileId, hltSource);
1759
1760 delete aFXSarray;
1761
1762 TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(kHLT),
1763 now.GetSec(), whereClause.Data());
1764
1765 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1766
1767 // Query execution
1768 TSQLResult* aResult;
1769 aResult = dynamic_cast<TSQLResult*> (fServer[kHLT]->Query(sqlQuery));
1770 if (!aResult) {
1771 Log(fCurrentDetector, Form("UpdateHLTTable - Can't execute SQL query <%s>", sqlQuery.Data()));
1772 return kFALSE;
1773 }
1774 delete aResult;
1775 }
1776
1777 return kTRUE;
1778}
57f50b3c 1779
2bb7b766 1780//______________________________________________________________________________________________
1781Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
1782{
1783// Update Shuttle logbook filling detector or shuttle_done column
1784// ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
57f50b3c 1785
2bb7b766 1786 // check connection, in case connect
be48e3ea 1787 if(!Connect(3)){
2bb7b766 1788 Log("SHUTTLE", "UpdateShuttleLogbook - Couldn't connect to DAQ Logbook.");
1789 return kFALSE;
57f50b3c 1790 }
1791
2bb7b766 1792 TString detName(detector);
1793 TString setClause;
1794 if(detName == "shuttle_done") {
1795 setClause = "set shuttle_done=1";
1796 } else {
2bb7b766 1797 TString statusStr(status);
1798 if(statusStr.Contains("done", TString::kIgnoreCase) ||
1799 statusStr.Contains("failed", TString::kIgnoreCase)){
eba76848 1800 setClause = Form("set %s=\"%s\"", detector, status);
2bb7b766 1801 } else {
1802 Log("SHUTTLE",
1803 Form("UpdateShuttleLogbook - Invalid status <%s> for detector %s",
1804 status, detector));
1805 return kFALSE;
1806 }
1807 }
57f50b3c 1808
2bb7b766 1809 TString whereClause = Form("where run=%d", GetCurrentRun());
1810
1811 TString sqlQuery = Form("update logbook_shuttle %s %s",
1812 setClause.Data(), whereClause.Data());
57f50b3c 1813
2bb7b766 1814 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1815
1816 // Query execution
1817 TSQLResult* aResult;
be48e3ea 1818 aResult = dynamic_cast<TSQLResult*> (fServer[3]->Query(sqlQuery));
2bb7b766 1819 if (!aResult) {
1820 Log("SHUTTLE", Form("UpdateShuttleLogbook - Can't execute query <%s>", sqlQuery.Data()));
1821 return kFALSE;
57f50b3c 1822 }
2bb7b766 1823 delete aResult;
57f50b3c 1824
1825 return kTRUE;
1826}
1827
1828//______________________________________________________________________________________________
2bb7b766 1829Int_t AliShuttle::GetCurrentRun() const
1830{
1831// Get current run from logbook entry
57f50b3c 1832
2bb7b766 1833 return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
57f50b3c 1834}
1835
1836//______________________________________________________________________________________________
2bb7b766 1837UInt_t AliShuttle::GetCurrentStartTime() const
1838{
1839// get current start time
57f50b3c 1840
2bb7b766 1841 return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
57f50b3c 1842}
1843
1844//______________________________________________________________________________________________
2bb7b766 1845UInt_t AliShuttle::GetCurrentEndTime() const
1846{
1847// get current end time from logbook entry
57f50b3c 1848
2bb7b766 1849 return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
57f50b3c 1850}
1851
b948db8d 1852//______________________________________________________________________________________________
1853void AliShuttle::Log(const char* detector, const char* message)
1854{
58bc3020 1855// Fill log string with a message
b948db8d 1856
84090f85 1857 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1858 if (dir == NULL) {
1859 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
2bb7b766 1860 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
84090f85 1861 return;
1862 }
b948db8d 1863
84090f85 1864 } else {
1865 gSystem->FreeDirectory(dir);
1866 }
b948db8d 1867
cb343cfd 1868 TString toLog = Form("%s (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
2bb7b766 1869 if(GetCurrentRun()>=0 ) toLog += Form("run %d - ", GetCurrentRun());
1870 toLog += Form("%s", message);
1871
84090f85 1872 AliInfo(toLog.Data());
b948db8d 1873
84090f85 1874 TString fileName;
1875 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1876 gSystem->ExpandPathName(fileName);
1877
1878 ofstream logFile;
1879 logFile.open(fileName, ofstream::out | ofstream::app);
1880
1881 if (!logFile.is_open()) {
1882 AliError(Form("Could not open file %s", fileName.Data()));
1883 return;
1884 }
7bfb2090 1885
84090f85 1886 logFile << toLog.Data() << "\n";
b948db8d 1887
84090f85 1888 logFile.close();
b948db8d 1889}
2bb7b766 1890
2bb7b766 1891//______________________________________________________________________________________________
1892Bool_t AliShuttle::Collect(Int_t run)
1893{
eba76848 1894//
1895// Collects conditions data for all UNPROCESSED run written to DAQ LogBook in case of run = -1 (default)
1896// If a dedicated run is given this run is processed
1897//
1898// In operational mode, this is the Shuttle function triggered by the EOR signal.
1899//
2bb7b766 1900
eba76848 1901 if (run == -1)
1902 Log("SHUTTLE","Collect - Shuttle called. Collecting conditions data for unprocessed runs");
1903 else
1904 Log("SHUTTLE", Form("Collect - Shuttle called. Collecting conditions data for run %d", run));
cb343cfd 1905
1906 SetLastAction("Starting");
2bb7b766 1907
1908 TString whereClause("where shuttle_done=0");
eba76848 1909 if (run != -1)
1910 whereClause += Form(" and run=%d", run);
2bb7b766 1911
1912 TObjArray shuttleLogbookEntries;
be48e3ea 1913 if (!QueryShuttleLogbook(whereClause, shuttleLogbookEntries))
1914 {
cb343cfd 1915 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
2bb7b766 1916 return kFALSE;
1917 }
1918
9e080f92 1919 if (shuttleLogbookEntries.GetEntries() == 0)
1920 {
1921 if (run == -1)
1922 Log("SHUTTLE","Collect - Found no UNPROCESSED runs in Shuttle logbook");
1923 else
1924 Log("SHUTTLE", Form("Collect - Run %d is already DONE "
1925 "or it does not exist in Shuttle logbook", run));
1926 return kTRUE;
1927 }
1928
be48e3ea 1929 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
1930 fFirstUnprocessed[iDet] = kTRUE;
1931
fc5a4708 1932 if (run != -1)
be48e3ea 1933 {
1934 // query Shuttle logbook for earlier runs, check if some detectors are unprocessed,
1935 // flag them into fFirstUnprocessed array
1936 TString whereClause(Form("where shuttle_done=0 and run < %d", run));
1937 TObjArray tmpLogbookEntries;
1938 if (!QueryShuttleLogbook(whereClause, tmpLogbookEntries))
1939 {
1940 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
1941 return kFALSE;
1942 }
1943
1944 TIter iter(&tmpLogbookEntries);
1945 AliShuttleLogbookEntry* anEntry = 0;
1946 while ((anEntry = dynamic_cast<AliShuttleLogbookEntry*> (iter.Next())))
1947 {
1948 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
1949 {
1950 if (anEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
1951 {
1952 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
1953 anEntry->GetRun(), GetDetName(iDet)));
1954 fFirstUnprocessed[iDet] = kFALSE;
1955 }
1956 }
1957
1958 }
1959
1960 }
1961
1962 if (!RetrieveConditionsData(shuttleLogbookEntries))
1963 {
cb343cfd 1964 Log("SHUTTLE", "Collect - Process of at least one run failed");
2bb7b766 1965 return kFALSE;
1966 }
1967
eba76848 1968 return kTRUE;
2bb7b766 1969}
1970
2bb7b766 1971//______________________________________________________________________________________________
1972Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
1973{
1974// Retrieve conditions data for all runs that aren't processed yet
1975
1976 Bool_t hasError = kFALSE;
1977
1978 TIter iter(&dateEntries);
1979 AliShuttleLogbookEntry* anEntry;
1980
1981 while ((anEntry = (AliShuttleLogbookEntry*) iter.Next())){
1982 if (!Process(anEntry)){
1983 hasError = kTRUE;
1984 }
1985 }
1986
1987 return hasError == kFALSE;
1988}
cb343cfd 1989
1990//______________________________________________________________________________________________
1991ULong_t AliShuttle::GetTimeOfLastAction() const
1992{
1993 ULong_t tmp;
1994
1995 fMonitoringMutex->Lock();
be48e3ea 1996
cb343cfd 1997 tmp = fLastActionTime;
1998
1999 fMonitoringMutex->UnLock();
2000
2001 return tmp;
2002}
2003
2004//______________________________________________________________________________________________
2005const TString AliShuttle::GetLastAction() const
2006{
2007 // returns a string description of the last action
2008
2009 TString tmp;
2010
2011 fMonitoringMutex->Lock();
2012
2013 tmp = fLastAction;
2014
2015 fMonitoringMutex->UnLock();
2016
2017 return tmp;
2018}
2019
2020//______________________________________________________________________________________________
2021void AliShuttle::SetLastAction(const char* action)
2022{
2023 // updates the monitoring variables
2024
2025 fMonitoringMutex->Lock();
2026
2027 fLastAction = action;
2028 fLastActionTime = time(0);
2029
2030 fMonitoringMutex->UnLock();
2031}
eba76848 2032
2033//______________________________________________________________________________________________
2034const char* AliShuttle::GetRunParameter(const char* param)
2035{
2036// returns run parameter read from DAQ logbook
2037
2038 if(!fLogbookEntry) {
2039 AliError("No logbook entry!");
2040 return 0;
2041 }
2042
2043 return fLogbookEntry->GetRunParameter(param);
2044}