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