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