More coding rule violations corrected.
[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$
4f0ab988 18Revision 1.12 2006/08/08 14:19:29 jgrosseo
19Update to shuttle classes (Alberto)
20
21- Possibility to set the full object's path in the Preprocessor's and
22Shuttle's Store functions
23- Possibility to extend the object's run validity in the same classes
24("startValidity" and "validityInfinite" parameters)
25- Implementation of the StoreReferenceData function to store reference
26data in a dedicated CDB storage.
27
84090f85 28Revision 1.11 2006/07/21 07:37:20 jgrosseo
29last run is stored after each run
30
7bfb2090 31Revision 1.10 2006/07/20 09:54:40 jgrosseo
32introducing status management: The processing per subdetector is divided into several steps,
33after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
34can keep track of the number of failures and skips further processing after a certain threshold is
35exceeded. These thresholds can be configured in LDAP.
36
5164a766 37Revision 1.9 2006/07/19 10:09:55 jgrosseo
38new configuration, accesst to DAQ FES (Alberto)
39
57f50b3c 40Revision 1.8 2006/07/11 12:44:36 jgrosseo
41adding parameters for extended validity range of data produced by preprocessor
42
17111222 43Revision 1.7 2006/07/10 14:37:09 jgrosseo
44small fix + todo comment
45
e090413b 46Revision 1.6 2006/07/10 13:01:41 jgrosseo
47enhanced storing of last sucessfully processed run (alberto)
48
a7160fe9 49Revision 1.5 2006/07/04 14:59:57 jgrosseo
50revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
51
45a493ce 52Revision 1.4 2006/06/12 09:11:16 jgrosseo
53coding conventions (Alberto)
54
58bc3020 55Revision 1.3 2006/06/06 14:26:40 jgrosseo
56o) removed files that were moved to STEER
57o) shuttle updated to follow the new interface (Alberto)
58
b948db8d 59Revision 1.2 2006/03/07 07:52:34 hristov
60New version (B.Yordanov)
61
d477ad88 62Revision 1.6 2005/11/19 17:19:14 byordano
63RetrieveDATEEntries and RetrieveConditionsData added
64
65Revision 1.5 2005/11/19 11:09:27 byordano
66AliShuttle declaration added
67
68Revision 1.4 2005/11/17 17:47:34 byordano
69TList changed to TObjArray
70
71Revision 1.3 2005/11/17 14:43:23 byordano
72import to local CVS
73
74Revision 1.1.1.1 2005/10/28 07:33:58 hristov
75Initial import as subdirectory in AliRoot
76
73abe331 77Revision 1.2 2005/09/13 08:41:15 byordano
78default startTime endTime added
79
80Revision 1.4 2005/08/30 09:13:02 byordano
81some docs added
82
83Revision 1.3 2005/08/29 21:15:47 byordano
84some docs added
85
86*/
87
88//
89// This class is the main manager for AliShuttle.
90// It organizes the data retrieval from DCS and call the
b948db8d 91// interface methods of AliPreprocessor.
73abe331 92// For every detector in AliShuttleConfgi (see AliShuttleConfig),
93// data for its set of aliases is retrieved. If there is registered
b948db8d 94// AliPreprocessor for this detector then it will be used
95// accroding to the schema (see AliPreprocessor).
96// If there isn't registered AliPreprocessor than the retrieved
73abe331 97// data is stored automatically to the undelying AliCDBStorage.
98// For detSpec is used the alias name.
99//
100
101#include "AliShuttle.h"
102
103#include "AliCDBManager.h"
104#include "AliCDBStorage.h"
105#include "AliCDBId.h"
84090f85 106#include "AliCDBRunRange.h"
107#include "AliCDBPath.h"
5164a766 108#include "AliCDBEntry.h"
73abe331 109#include "AliShuttleConfig.h"
110#include "AliDCSClient.h"
111#include "AliLog.h"
b948db8d 112#include "AliPreprocessor.h"
5164a766 113#include "AliShuttleStatus.h"
73abe331 114
57f50b3c 115#include <TSystem.h>
58bc3020 116#include <TObject.h>
b948db8d 117#include <TString.h>
57f50b3c 118#include <TTimeStamp.h>
73abe331 119#include <TObjString.h>
57f50b3c 120#include <TSQLServer.h>
121#include <TSQLResult.h>
122#include <TSQLRow.h>
73abe331 123
5164a766 124#include <fstream>
125
73abe331 126ClassImp(AliShuttle)
127
4f0ab988 128TString AliShuttle::fgkMainCDB("alien://DBFolder=ShuttleCDB");
84090f85 129TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
130TString AliShuttle::fgkMainRefStorage("alien://DBFolder=ShuttleReference");
131TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
132
4f0ab988 133Bool_t AliShuttle::fgkProcessDCS(kTRUE);
134
135
84090f85 136const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
137const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
57f50b3c 138
139const char* AliShuttle::fgkDetectorName[AliShuttle::fgkNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
140 "PHOS", "CPV", "RICH", "EMCAL", "MUON_TRK", "MUON_TRG", "FMD", "ZDC", "PMD", "START", "VZERO"};
141
142const char* AliShuttle::fgkDetectorCode[AliShuttle::fgkNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
143 "PHS", "CPV", "HMP", "EMC", "MCH", "MTR", "FMD", "ZDC", "PMD", "T00", "V00"};
b948db8d 144
145//______________________________________________________________________________________________
146AliShuttle::AliShuttle(const AliShuttleConfig* config,
147 UInt_t timeout, Int_t retries):
4f0ab988 148fConfig(config),
149fTimeout(timeout), fRetries(retries),
150fPreprocessorMap(),
151fCurrentRun(-1),
152fCurrentStartTime(0), fCurrentEndTime(0),
153fCurrentDetector(""),
154fStatusEntry(0)
73abe331 155{
156 //
157 // config: AliShuttleConfig used
73abe331 158 // timeout: timeout used for AliDCSClient connection
159 // retries: the number of retries in case of connection error.
160 //
161
57f50b3c 162 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
163 for(int iSys=0;iSys<3;iSys++) {
164 fServer[iSys]=0;
165 fFESlist[iSys].SetOwner(kTRUE);
166 }
73abe331 167}
168
58bc3020 169//______________________________________________________________________
170AliShuttle::AliShuttle(const AliShuttle& /*other*/):
4f0ab988 171AliShuttleInterface(),
172fConfig(0),
173fTimeout(0), fRetries(0),
174fPreprocessorMap(),
175fCurrentRun(-1),
176fCurrentStartTime(0), fCurrentEndTime(0),
177fCurrentDetector(""),
178fStatusEntry(0)
179
58bc3020 180{
181// copy constructor (not implemented)
182
183}
184
185//______________________________________________________________________
186AliShuttle &AliShuttle::operator=(const AliShuttle& /*other*/)
187{
188// assignment operator (not implemented)
189
190return *this;
191}
192
b948db8d 193//______________________________________________________________________________________________
57f50b3c 194AliShuttle::~AliShuttle()
58bc3020 195{
196// destructor
197
b948db8d 198 fPreprocessorMap.DeleteAll();
57f50b3c 199 for(int iSys=0;iSys<3;iSys++)
200 if(fServer[iSys]) {
201 fServer[iSys]->Close();
202 delete fServer[iSys];
203 }
73abe331 204}
205
b948db8d 206//______________________________________________________________________________________________
57f50b3c 207void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
58bc3020 208{
73abe331 209 //
b948db8d 210 // Registers new AliPreprocessor.
73abe331 211 // It uses GetName() for indentificator of the pre processor.
212 // The pre processor is registered it there isn't any other
213 // with the same identificator (GetName()).
214 //
215
b948db8d 216 if (fPreprocessorMap.GetValue(preprocessor->GetName())) {
217 AliWarning(Form("AliPreprocessor %s is already registered!",
218 preprocessor->GetName()));
73abe331 219 return;
220 }
221
b948db8d 222 fPreprocessorMap.Add(new TObjString(preprocessor->GetName()), preprocessor);
73abe331 223}
224
b948db8d 225//______________________________________________________________________________________________
84090f85 226UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
227 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
73abe331 228{
84090f85 229 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
230 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
231 // using this function. Use StoreReferenceData instead!
232 //
233
234 // The parameters are
235 // 1) the object's path.
236 // 2) the object to be stored
237 // 3) the metaData to be associated with the object
238 // 4) the validity start run number w.r.t. the current run,
239 // if the data is valid only for this run leave the default 0
240 // 5) specifies if the calibration data is valid for infinity (this means until updated),
241 // typical for calibration runs, the default is kFALSE
17111222 242 //
17111222 243 //
84090f85 244 // returns 0 if fail
245 // 1 if stored in main (Grid) CDB storage
246 // 2 if stored in backup (Local) CDB storage
b948db8d 247
73abe331 248
84090f85 249 Int_t firstRun = GetCurrentRun() - validityStart;
250 if(firstRun < 0) {
251 AliError("First valid run happens to be less than 0! Setting it to 0...");
252 firstRun=0;
253 }
254
255 Int_t lastRun = -1;
256 if(validityInfinite) {
257 lastRun = AliCDBRunRange::Infinity();
258 } else {
259 lastRun = GetCurrentRun();
260 }
261
262 AliCDBId id(path, firstRun, lastRun);
b948db8d 263
a7160fe9 264 UInt_t result = 0;
84090f85 265
4f0ab988 266 if (!(AliCDBManager::Instance()->GetStorage(fgkMainCDB))) {
267 Log(fCurrentDetector, "Cannot activate main CDB storage!");
a7160fe9 268 } else {
4f0ab988 269 result = (UInt_t) AliCDBManager::Instance()->GetStorage(fgkMainCDB)
270 ->Put(object, id, metaData);
a7160fe9 271 }
4f0ab988 272
b948db8d 273 if(!result) {
274
84090f85 275 Log(fCurrentDetector,
276 "Error while storing object in main storage: it will go to local storage!");
b948db8d 277
84090f85 278 result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)
b948db8d 279 ->Put(object, id, metaData);
280
281 if(result) {
282 result = 2;
283 }else{
84090f85 284 Log(fCurrentDetector, "Can't store data!");
285 }
286 }
287 return result;
288
289}
290
291//______________________________________________________________________________________________
292UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object,
293 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
294{
295 // Stores a CDB object in the storage for reference data. This objects will not be available during
296 // offline reconstrunction. Use this function for reference data only!
297 //
298
299 // The parameters are
300 // 1) the object's path.
301 // 2) the object to be stored
302 // 3) the metaData to be associated with the object
303 // 4) the validity start run number w.r.t. the current run,
304 // if the data is valid only for this run leave the default 0
305 // 5) specifies if the calibration data is valid for infinity (this means until updated),
306 // typical for calibration runs, the default is kFALSE
307 //
308 //
309 // returns 0 if fail
310 // 1 if stored in main (Grid) reference storage
311 // 2 if stored in backup (Local) reference storage
312
313 Int_t firstRun = GetCurrentRun() - validityStart;
314 if(firstRun < 0) {
315 AliError("First valid run happens to be less than 0! Setting it to 0...");
316 firstRun=0;
317 }
318
319 Int_t lastRun = -1;
320 if(validityInfinite) {
321 lastRun = AliCDBRunRange::Infinity();
322 } else {
323 lastRun = GetCurrentRun();
324 }
325
326 AliCDBId id(path, firstRun, lastRun);
327
328 UInt_t result = 0;
329
330 if (!(AliCDBManager::Instance()->GetStorage(fgkMainRefStorage))) {
331 Log(fCurrentDetector, "Cannot activate main reference storage!");
332 } else {
333 result = (UInt_t) AliCDBManager::Instance()->GetStorage(fgkMainRefStorage)
334 ->Put(object, id, metaData);
335 }
336
337 if(!result) {
338
339 Log(fCurrentDetector,
340 "Error while storing object in main reference storage: it will go to local ref storage!");
341
342 result = AliCDBManager::Instance()->GetStorage(fgkLocalRefStorage)
343 ->Put(object, id, metaData);
344
345 if(result) {
346 result = 2;
347 }else{
348 Log(fCurrentDetector, "Can't store reference data!");
b948db8d 349 }
350 }
351 return result;
352
73abe331 353}
354
b948db8d 355//______________________________________________________________________________________________
5164a766 356AliShuttleStatus* AliShuttle::ReadShuttleStatus()
357{
358 // Reads the AliShuttleStatus from the CDB
359
360 if (fStatusEntry)
361 {
362 delete fStatusEntry;
363 fStatusEntry = 0;
364 }
365
84090f85 366 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
5164a766 367 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), fCurrentRun);
368
5164a766 369 if (!fStatusEntry)
370 return 0;
371
372 TObject* anObject = fStatusEntry->GetObject();
373 if (anObject == NULL || anObject->IsA() != AliShuttleStatus::Class())
374 {
375 AliError("Invalid object stored to CDB!");
376 return 0;
377 }
378
379 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (anObject);
380 return status;
381}
382
383//______________________________________________________________________________________________
7bfb2090 384Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
5164a766 385{
386 // writes the status for one subdetector
387
388 if (fStatusEntry)
389 {
390 delete fStatusEntry;
391 fStatusEntry = 0;
392 }
393
394 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), fCurrentRun, fCurrentRun);
395
396 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
397
84090f85 398 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
7bfb2090 399
400 if (!result)
401 {
402 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), fCurrentRun));
403 return kFALSE;
404 }
405
406 return kTRUE;
5164a766 407}
408
409//______________________________________________________________________________________________
410void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
411{
412 // changes the AliShuttleStatus for the given detector and run to the given status
413
414 if (!fStatusEntry)
415 {
416 AliError("UNEXPECTED: fStatusEntry empty");
417 return;
418 }
419
420 TObject* anObject = fStatusEntry->GetObject();
421 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (anObject);
422
423 if (!status)
424 {
425 AliError("UNEXPECTED: status could not be read from current CDB entry");
426 return;
427 }
428
7bfb2090 429 Log("SHUTTLE", Form("%s: Changing state from %s to %s", fCurrentDetector.Data(),
430 status->GetStatusName(), status->GetStatusName(newStatus)));
5164a766 431
432 status->SetStatus(newStatus);
433 if (increaseCount)
434 status->IncreaseCount();
435
84090f85 436 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
5164a766 437}
438
439//______________________________________________________________________________________________
440Bool_t AliShuttle::ContinueProcessing()
441{
442 // this function reads the AliShuttleStatus information from CDB and
443 // checks if the processing should be continued
444 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
445
446 AliShuttleStatus* status = ReadShuttleStatus();
447 if (!status)
448 {
449 // first time
450
451 Log("SHUTTLE", Form("%s: Processing first time.", fCurrentDetector.Data()));
452 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
7bfb2090 453 return WriteShuttleStatus(status);
5164a766 454 }
455
456 if (status->GetStatus() == AliShuttleStatus::kDone)
457 {
458 Log("SHUTTLE", Form("%s already done for run %d", fCurrentDetector.Data(), fCurrentRun));
459 return kFALSE;
460 }
461
462 if (status->GetStatus() == AliShuttleStatus::kFailed)
463 {
464 Log("SHUTTLE", Form("%s already in failed state for run %d", fCurrentDetector.Data(), fCurrentRun));
465 return kFALSE;
466 }
467
468 // if we get here, there is a restart
469
470 // abort conditions
7bfb2090 471 if (status->GetStatus() == AliShuttleStatus::kPPStarted && status->GetCount() >= fConfig->GetMaxPPRetries() ||
472 status->GetCount() >= fConfig->GetMaxRetries())
5164a766 473 {
7bfb2090 474 Log("SHUTTLE", Form("%s, run %d failed too often, %d times, status %s. Skipping processing.",
475 fCurrentDetector.Data(), fCurrentRun, status->GetCount(), status->GetStatusName()));
5164a766 476
477 return kFALSE;
478 }
479
7bfb2090 480 Log("SHUTTLE", Form("Restart of %s, run %d. Got stuck before in %s, count %d",
481 fCurrentDetector.Data(), fCurrentRun, status->GetStatusName(), status->GetCount()));
5164a766 482
483 UpdateShuttleStatus(AliShuttleStatus::kStarted, kTRUE);
484
485 return kTRUE;
486}
487
488//______________________________________________________________________________________________
489Bool_t AliShuttle::Process(Int_t run, UInt_t startTime, UInt_t endTime)
58bc3020 490{
73abe331 491 //
b948db8d 492 // Makes data retrieval for all detectors in the configuration.
73abe331 493 // run: is the run number used
494 // startTime: is the run start time
495 // endTime: is the run end time
d477ad88 496 // Returns kFALSE in case of error occured and kTRUE otherwise
73abe331 497 //
498
57f50b3c 499 AliInfo(Form("\n\n ^*^*^*^*^*^* Processing run %d ^*^*^*^*^*^*", run));
500
501 // Initialization
d477ad88 502 Bool_t hasError = kFALSE;
57f50b3c 503 for(Int_t iSys=0;iSys<3;iSys++) fFESCalled[iSys]=kFALSE;
5164a766 504
7bfb2090 505 fCurrentRun = run;
57f50b3c 506 fCurrentStartTime = startTime;
507 fCurrentEndTime = endTime;
d477ad88 508
57f50b3c 509 // Loop on detectors in the configuration
b948db8d 510 TIter iter(fConfig->GetDetectors());
73abe331 511 TObjString* aDetector;
b948db8d 512
73abe331 513 while ((aDetector = (TObjString*) iter.Next())) {
7bfb2090 514 fCurrentDetector = aDetector->String();
5164a766 515
57f50b3c 516 Bool_t detectorError=kFALSE;
5164a766 517 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
518
7bfb2090 519 if (ContinueProcessing() == kFALSE) continue;
5164a766 520
521 if(!Process()) {
d477ad88 522 hasError = kTRUE;
57f50b3c 523 detectorError=kTRUE;
524 continue;
d477ad88 525 }
57f50b3c 526 AliInfo(Form("Process ended successfully for detector %s!",aDetector->GetName()));
527
528 // Process successful: Update time_processed field in FES logbooks!
529 if(fFESCalled[kDAQ]) {
5164a766 530 hasError = (UpdateDAQTable() == kFALSE);
57f50b3c 531 fFESlist[kDAQ].Clear();
532 }
533 //if(fFESCalled[kDCS]) {
534 // hasError = UpdateDCSTable(aDetector->GetName());
535 // fFESlist[kDCS].Clear();
536 //}
537 //if(fFESCalled[kHLT]) {
538 // hasError = UpdateHLTTable(aDetector->GetName());
539 // fFESlist[kHLT].Clear();
540 //}
d477ad88 541
7bfb2090 542 UpdateShuttleStatus(AliShuttleStatus::kDone);
543 }
5164a766 544
57f50b3c 545 fCurrentRun = -1;
546 fCurrentStartTime = 0;
547 fCurrentEndTime = 0;
b948db8d 548
a7160fe9 549 return hasError == kFALSE;
73abe331 550}
551
b948db8d 552//______________________________________________________________________________________________
5164a766 553Bool_t AliShuttle::Process()
73abe331 554{
555 //
b948db8d 556 // Makes data retrieval just for one specific detector.
73abe331 557 // Threre should be a configuration for this detector.
558 // run: is the run number used
559 // startTime: is the run start time
560 // endTime: is the run end time
561 // detector: detector for which the retrieval will be made
d477ad88 562 // Returns kFALSE in case of error occured and kTRUE otherwise
73abe331 563 //
564
5164a766 565 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), fCurrentRun));
73abe331 566
5164a766 567 if (!fConfig->HasDetector(fCurrentDetector)) {
568 Log(fCurrentDetector, "There isn't any configuration for %s !");
7bfb2090 569 UpdateShuttleStatus(AliShuttleStatus::kFailed);
d477ad88 570 return kFALSE;
73abe331 571 }
572
7bfb2090 573 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
73abe331 574
7bfb2090 575 TString host(fConfig->GetDCSHost(fCurrentDetector));
5164a766 576 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
577
578 TIter iter(fConfig->GetDCSAliases(fCurrentDetector));
73abe331 579 TObjString* anAlias;
b948db8d 580 TMap aliasMap;
73abe331 581
d477ad88 582 Bool_t hasError = kFALSE;
b948db8d 583 Bool_t result=kFALSE;
d477ad88 584
b948db8d 585 while ((anAlias = (TObjString*) iter.Next())) {
d477ad88 586 TObjArray valueSet;
4f0ab988 587 // TODO Test only... I've added a flag that allows to
588 // exclude DCS archive DB query
589 if(fgkProcessDCS){
590 AliInfo("Querying DCS archive DB data...");
591 result = GetValueSet(host, port, anAlias->String(), valueSet);
592 } else {
593 AliInfo(Form("Skipping DCS processing. Port = %d",port));
594 result = kTRUE;
595 }
b948db8d 596 if(result) {
597 aliasMap.Add(anAlias->Clone(), valueSet.Clone());
598 }else{
57f50b3c 599 TString message = Form("Error while retrieving alias %s !",
b948db8d 600 anAlias->GetName());
5164a766 601 Log(fCurrentDetector, message.Data());
b948db8d 602 hasError = kTRUE;
84090f85 603 break;
73abe331 604 }
605 }
b948db8d 606
5164a766 607 if (hasError)
7bfb2090 608 {
609 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
610 return kFALSE;
611 }
5164a766 612
613 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
a7160fe9 614
5164a766 615 AliPreprocessor* aPreprocessor =
616 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
a7160fe9 617 if(aPreprocessor)
618 {
5164a766 619 aPreprocessor->Initialize(fCurrentRun, fCurrentStartTime, fCurrentEndTime);
4f0ab988 620
621 // TODO Think about what to do in case of "Grid storage error"
622 // (-> object put in local backup storage, return 2)
a7160fe9 623 hasError = (aPreprocessor->Process(&aliasMap) == 0);
624 }else{
e090413b 625 // TODO default behaviour?
5164a766 626 AliInfo(Form("No Preprocessor for %s: storing TMap of DP arrays into CDB!", fCurrentDetector.Data()));
a7160fe9 627 AliCDBMetaData metaData;
5164a766 628 AliDCSValue dcsValue(fCurrentStartTime, fCurrentEndTime);
a7160fe9 629 metaData.SetResponsible(Form("Duck, Donald"));
57f50b3c 630 metaData.SetProperty("StartEndTime", &dcsValue);
a7160fe9 631 metaData.SetComment("Automatically stored by Shuttle!");
84090f85 632 AliCDBPath path(fCurrentDetector,"DCS","Data");
633 hasError = (Store(path, &aliasMap, &metaData) == 0);
b948db8d 634 }
635
5164a766 636 if (hasError)
637 UpdateShuttleStatus(AliShuttleStatus::kPPError);
638 else
639 UpdateShuttleStatus(AliShuttleStatus::kPPDone);
b948db8d 640
a7160fe9 641 aliasMap.Delete();
b948db8d 642
a7160fe9 643 return hasError == kFALSE;
73abe331 644}
645
b948db8d 646//______________________________________________________________________________________________
73abe331 647Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* alias,
d477ad88 648 TObjArray& valueSet)
73abe331 649{
58bc3020 650// Retrieve all "alias" data points from the DCS server
651// host, port: TSocket connection parameters
652// alias: name of the alias
653// valueSet: array of retrieved AliDCSValue's
654
73abe331 655 AliDCSClient client(host, port, fTimeout, fRetries);
656 if (!client.IsConnected()) {
b948db8d 657 return kFALSE;
73abe331 658 }
659
57f50b3c 660 Int_t result = client.GetAliasValues(alias,
73abe331 661 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
662
663 if (result < 0) {
664 AliError(Form("Can't get '%s'! Reason: %s",
665 alias, AliDCSClient::GetErrorString(result)));
666
667 if (result == AliDCSClient::fgkServerError) {
668 AliError(Form("Server error: %s",
669 client.GetServerError().Data()));
670 }
671
672 return kFALSE;
673 }
674
675 return kTRUE;
676}
b948db8d 677
678//______________________________________________________________________________________________
57f50b3c 679const char* AliShuttle::GetFile(Int_t system, const char* detector,
680 const char* id, const char* source)
b948db8d 681{
57f50b3c 682// Get calibration file from file exchange servers
683// calls specific getter according to system index (kDAQ, kDCS, kHLT)
684
685 switch(system){
686 case kDAQ:
687 return GetDAQFileName(detector, id, source);
688 break;
689 case kDCS:
690 return GetDCSFileName(detector, id, source);
691 break;
692 case kHLT:
693 return GetHLTFileName(detector, id, source);
694 break;
695 default:
696 AliError(Form("No valid system index: %d",system));
697 }
b948db8d 698
b948db8d 699 return 0;
700}
701
b948db8d 702//______________________________________________________________________________________________
57f50b3c 703TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
b948db8d 704{
57f50b3c 705// Get sources producing the condition file Id from file exchange servers
706// calls specific getter according to system index (kDAQ, kDCS, kHLT)
707
708 switch(system){
709 case kDAQ:
710 return GetDAQFileSources(detector, id);
711 break;
712 case kDCS:
713 return GetDCSFileSources(detector, id);
714 break;
715 case kHLT:
716 return GetHLTFileSources(detector, id);
717 break;
718 default:
719 AliError(Form("No valid system index: %d",system));
720 }
721
722 return NULL;
723}
724
725//______________________________________________________________________________________________
726Bool_t AliShuttle::Connect(Int_t system){
727// Connect to MySQL Server of the system's FES logbook
728
729 // check connection: if already connected return
730 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
731
732 TString aFESlbHost= Form("mysql://%s", fConfig->GetFESlbHost(system));
733
734 fServer[system] = TSQLServer::Connect(aFESlbHost,
735 fConfig->GetFESlbUser(system),
736 fConfig->GetFESlbPass(system));
737 if (!fServer[system] || !fServer[system]->IsConnected()) {
738 AliError(Form("Can't establish connection to FES logbook for %s !",fkSystemNames[system]));
739 return kFALSE;
740 }
741
742 // Get tables
743 // TODO in the configuration should the table name be there too?
744 switch(system){
745 case kDAQ:
746 fServer[kDAQ]->GetTables("REFSYSLOG");
747 break;
748 case kDCS:
749 //fServer[kDCS]->GetTables("REFSYSLOG");
750 break;
751 case kHLT:
752 //fServer[kHLT]->GetTables("REFSYSLOG");
753 break;
754 default:
755 break;
756 }
757
758 return kTRUE;
759}
760
761//______________________________________________________________________________________________
762const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source){
763// Retrieves a file from the DAQ FES.
764// First queris the DAQ logbook_fs for the DAQ file name, using the run, detector, id and source info
765// then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
766// run: current run being processed (fCurrentRun)
767// detector: comes from the Preprocessor name (must be converted into detector code with GetDetCode)
768// id: provided as a parameter by the Preprocessor
769// source: provided by the Preprocessor through GetFileSources function
770
771 // check connection, in case connect
772 if(!Connect(kDAQ)){
773 Log(detector, "GetDAQFileName: Couldn't connect to DAQ Logbook !");
774 return 0;
775 }
776
777 // Query preparation
778 TString sqlQueryStart = "select filePath from logbook_fs where";
779 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
780 fCurrentRun, GetDetCode(detector), id, source);
781 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
782
84090f85 783 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 784
785 // Query execution
786 TSQLResult* aResult;
787 aResult = fServer[kDAQ]->Query(sqlQuery);
788 if (!aResult) {
789 Log(detector, Form("Can't execute query <%s>!", sqlQuery.Data()));
790 return 0;
791 }
792
793 if (aResult->GetRowCount() == 0) {
794 Log(detector,
795 Form("GetDAQFileName: No result from SQL query <%s>!", sqlQuery.Data()));
796 delete aResult;
797 return 0;
798 }
799
800 if (aResult->GetRowCount() >1) {
801 Log(detector,
802 Form("GetDAQFileName: More than one row resulting from SQL query <%s>!", sqlQuery.Data()));
803 delete aResult;
804 return 0;
805 }
806
807 TSQLRow* aRow = aResult->Next();
808
809 if(!aRow){
810 Log(detector, Form("GetDAQFileName: Empty set result from query <%s>!", sqlQuery.Data()));
811 delete aResult;
812 return 0;
813 }
814
815 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
816
817 delete aResult;
818
84090f85 819 AliDebug(2, Form("filePath = %s",filePath.Data()));
57f50b3c 820
821 // retrieved file is renamed to make it unique
822 TString localFileName = Form("%s_%d_%s_%s.shuttle",
823 detector, fCurrentRun, id, source);
824
825 // file retrieval from DAQ FES
826 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
827 if(!result) {
828 Log(detector, Form("copying file %s from DAQ FES failed!", filePath.Data()));
829 return 0;
830 } else {
831 AliInfo(Form("File %s copied from DAQ FES into %s/%s !",
832 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
833 }
834
835
836 fFESCalled[kDAQ]=kTRUE;
837 TObjString *fileParams = new TObjString(Form("%s_!?!_%s", id, source));
838 fFESlist[kDAQ].Add(fileParams);
839
840 return localFileName.Data();
841
842}
843
844//______________________________________________________________________________________________
845Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName){
846
847 // check temp directory: trying to cd to temp; if it does not exist, create it
84090f85 848 AliDebug(2, Form("Copy file %s from DAQ FES into folder %s and rename it as %s",
57f50b3c 849 daqFileName,fgkShuttleTempDir, localFileName));
850
851 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
852 if (dir == NULL) {
853 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
854 AliError(Form("Can't open directory <%s>!", fgkShuttleTempDir));
855 return kFALSE;
856 }
857
858 } else {
859 gSystem->FreeDirectory(dir);
860 }
861
862 TString baseDAQFESFolder = "DAQ";
863 TString command = Form("scp %s@%s:%s/%s %s/%s",
864 fConfig->GetFESUser(kDAQ),
865 fConfig->GetFESHost(kDAQ),
866 baseDAQFESFolder.Data(),
867 daqFileName,
868 fgkShuttleTempDir,
869 localFileName);
870
84090f85 871 AliDebug(2, Form("%s",command.Data()));
57f50b3c 872
873 UInt_t nRetries = 0;
874 UInt_t maxRetries = 3;
875
876 // copy!! if successful TSystem::Exec returns 0
877 while(nRetries++ < maxRetries) {
84090f85 878 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
57f50b3c 879 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
880 }
881
882 return kFALSE;
883
884}
885
886//______________________________________________________________________________________________
887TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id){
888// Retrieves a file from the DCS FES.
889
890 // check connection, in case connect
891 if(!Connect(kDAQ)){
892 Log(detector, "GetDAQFileName: Couldn't connect to DAQ Logbook !");
893 return 0;
894 }
895
896 // Query preparation
897 TString sqlQueryStart = "select DAQsource from logbook_fs where";
898 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
899 fCurrentRun, GetDetCode(detector), id);
900 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
901
84090f85 902 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 903
904 // Query execution
905 TSQLResult* aResult;
906 aResult = fServer[kDAQ]->Query(sqlQuery);
907 if (!aResult) {
908 Log(detector, Form("GetDAQFileSources: Can't execute query <%s>!", sqlQuery.Data()));
909 return 0;
910 }
911
912 if (aResult->GetRowCount() == 0) {
913 Log(detector,
914 Form("GetDAQFileSources: No result from SQL query <%s>!", sqlQuery.Data()));
915 delete aResult;
916 return 0;
917 }
918
919 TSQLRow* aRow;
920 TList *list = new TList();
921 list->SetOwner(1);
922
923 while((aRow = aResult->Next())){
924
925 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
84090f85 926 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
57f50b3c 927 list->Add(new TObjString(daqSource));
928 }
929 delete aResult;
930
931 return list;
932
933}
934
935//______________________________________________________________________________________________
5164a766 936Bool_t AliShuttle::UpdateDAQTable(){
57f50b3c 937// Update DAQ table filling time_processed field in all rows corresponding to current run and detector
938
939 // check connection, in case connect
940 if(!Connect(kDAQ)){
5164a766 941 Log(fCurrentDetector, "UpdateDAQTable: Couldn't connect to DAQ Logbook !");
57f50b3c 942 return kFALSE;
943 }
944
945 TTimeStamp now; // now
946
947 // Loop on FES list entries
948 TIter iter(&fFESlist[kDAQ]);
949 TObjString *aFESentry=0;
950 while((aFESentry = dynamic_cast<TObjString*> (iter.Next()))){
951 TString aFESentrystr = aFESentry->String();
952 TObjArray *aFESarray = aFESentrystr.Tokenize("_!?!_");
953 if(!aFESarray || aFESarray->GetEntries() != 2 ) {
5164a766 954 Log(fCurrentDetector,Form("UpdateDAQTable: error updating FES entry! string = %s",
57f50b3c 955 aFESentrystr.Data()));
956 if(aFESarray) delete aFESarray;
957 return kFALSE;
958 }
959 const char* fileId = ((TObjString*) aFESarray->At(0))->GetName();
960 const char* daqSource = ((TObjString*) aFESarray->At(1))->GetName();
961 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
5164a766 962 fCurrentRun,GetDetCode(fCurrentDetector), fileId, daqSource);
57f50b3c 963
964 delete aFESarray;
965
966 TString sqlQuery = Form("update logbook_fs set time_processed=%d %s", now.GetSec(), whereClause.Data());
967
84090f85 968 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
57f50b3c 969
970 // Query execution
971 TSQLResult* aResult;
972 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
973 if (!aResult) {
5164a766 974 Log(fCurrentDetector, Form("UpdateDAQTable: Can't execute query <%s>!", sqlQuery.Data()));
57f50b3c 975 return kFALSE;
976 }
977 delete aResult;
978
979 // check result - TODO Is it necessary?
980 sqlQuery = Form("select time_processed from logbook_fs %s", whereClause.Data());
84090f85 981 AliDebug(2, Form(" CHECK - SQL query: \n%s",sqlQuery.Data()));
57f50b3c 982
983 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
984 if (!aResult) {
985 AliWarning("Can't check result!");
986 continue;
987 }
988
989 if (aResult->GetRowCount() == 0) {
5164a766 990 Log(fCurrentDetector,
57f50b3c 991 Form("GetDAQFileName: No result from SQL query <%s>!", sqlQuery.Data()));
992 delete aResult;
993 //return 0;
994 }
995
996 if (aResult->GetRowCount() >1) {
5164a766 997 Log(fCurrentDetector,
57f50b3c 998 Form("GetDAQFileName: More than one row resulting from SQL query <%s>!", sqlQuery.Data()));
999 delete aResult;
1000 //return 0;
1001 }
1002
1003 TSQLRow *row = dynamic_cast<TSQLRow*> (aResult->Next());
1004 TString processedTimeString(row->GetField(0), row->GetFieldLength(0));
1005 Int_t processedTime = processedTimeString.Atoi();
1006 if(processedTime != now.GetSec()){
5164a766 1007 Log(fCurrentDetector, Form("UpdateDAQTable: Update table error: processed_time=%d, now=%d !",
57f50b3c 1008 processedTime, now.GetSec()));
1009 delete aResult;
1010 return kFALSE;
1011 }
1012
1013 delete aResult;
1014
1015 }
1016
1017 return kTRUE;
1018}
1019
1020//______________________________________________________________________________________________
1021const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1022// Retrieves a file from the DCS FES.
1023
1024return "You're in DCS";
1025
1026}
1027
1028//______________________________________________________________________________________________
1029TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
1030// Retrieves a file from the DCS FES.
1031
1032return NULL;
1033
1034}
1035
1036//______________________________________________________________________________________________
1037const char* AliShuttle::GetHLTFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1038// Retrieves a file from the HLT FES.
1039
1040return "You're in HLT";
1041
1042}
1043
1044//______________________________________________________________________________________________
1045TList* AliShuttle::GetHLTFileSources(const char* /*detector*/, const char* /*id*/){
1046// Retrieves a file from the HLT FES.
1047
1048return NULL;
1049
1050}
1051
1052//______________________________________________________________________________________________
1053const char* AliShuttle::GetDetCode(const char* detector){
1054// Return detector code
1055
1056 for(int iDet=0; iDet < fgkNDetectors; iDet++){
1057 if(!strcmp(fgkDetectorName[iDet], detector)) return fgkDetectorCode[iDet];
1058 }
b948db8d 1059
b948db8d 1060 return 0;
1061}
1062
1063//______________________________________________________________________________________________
1064void AliShuttle::Log(const char* detector, const char* message)
1065{
58bc3020 1066// Fill log string with a message
b948db8d 1067
84090f85 1068 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1069 if (dir == NULL) {
1070 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
1071 AliError(Form("Can't open directory <%s>!", fgkShuttleTempDir));
1072 return;
1073 }
b948db8d 1074
84090f85 1075 } else {
1076 gSystem->FreeDirectory(dir);
1077 }
b948db8d 1078
84090f85 1079 TString toLog = Form("%s: %s, run %d - %s", TTimeStamp(time(0)).AsString(),
1080 detector, GetCurrentRun(), message);
1081 AliInfo(toLog.Data());
b948db8d 1082
84090f85 1083 TString fileName;
1084 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1085 gSystem->ExpandPathName(fileName);
1086
1087 ofstream logFile;
1088 logFile.open(fileName, ofstream::out | ofstream::app);
1089
1090 if (!logFile.is_open()) {
1091 AliError(Form("Could not open file %s", fileName.Data()));
1092 return;
1093 }
7bfb2090 1094
84090f85 1095 logFile << toLog.Data() << "\n";
b948db8d 1096
84090f85 1097 logFile.close();
b948db8d 1098}