]> git.uio.no Git - u/mrichter/AliRoot.git/blame - SHUTTLE/AliShuttle.cxx
bug fix in the name of the raw tag files (Raw instead of raw)
[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$
955d2abc 18Revision 1.75 2007/12/18 15:42:14 jgrosseo
19adding number of open runs to monitoring
20
fbc112e3 21Revision 1.74 2007/12/17 03:23:32 jgrosseo
22several bugfixes
23added "empty preprocessor" as placeholder for Acorde in FDR
24
4508ab8b 25Revision 1.73 2007/12/14 19:31:36 acolla
26Sending email to DCS experts is temporarily commented
27
b5f1c82e 28Revision 1.72 2007/12/13 15:44:28 acolla
29Run type added in mail sent to detector expert (eases understanding)
30
6a1146c4 31Revision 1.71 2007/12/12 14:56:14 jgrosseo
32sending shuttle_ignore to ML also in case of 0 events
33
97e3c167 34Revision 1.70 2007/12/12 13:45:35 acolla
35Monalisa started in Collect() function. Alive message to monitor is sent at each Collect and every minute during preprocessor processing.
36
ee6f7523 37Revision 1.69 2007/12/12 10:06:29 acolla
38in AliShuttle.cxx: SHUTTLE logbook is updated in case of invalid run times:
39
40time_start==0 && time_end==0
41
42logbook is NOT updated if time_start != 0 && time_end == 0, because it may mean that the run is still ongoing.
43
1abfbb60 44Revision 1.68 2007/12/11 10:15:17 acolla
45Added marking SHUTTLE=DONE for invalid runs
46(invalid start time or end time) and runs with totalEvents < 1
47
b0e53b15 48Revision 1.67 2007/12/07 19:14:36 acolla
49in AliShuttleTrigger:
50
51Added automatic collection of new runs on a regular time basis (settable from the configuration)
52
53in AliShuttleConfig: new members
54
55- triggerWait: time to wait for DIM trigger (s) before starting automatic collection of new runs
56- mode: run mode (test, prod) -> used to build log folder (logs or logs_PROD)
57
58in AliShuttle:
59
60- logs now stored in logs/#RUN/DET_#RUN.log
61
7d4cf768 62Revision 1.66 2007/12/05 10:45:19 jgrosseo
63changed order of arguments to TMonaLisaWriter
64
468df1ce 65Revision 1.65 2007/11/26 16:58:37 acolla
66Monalisa configuration added: host and table name
67
b832ec02 68Revision 1.64 2007/11/13 16:15:47 acolla
69DCS map is stored in a file in the temp folder where the detector is processed.
70If the preprocessor fails, the temp folder is not removed. This will help the debugging of the problem.
71
b1d18693 72Revision 1.63 2007/11/02 10:53:16 acolla
73Protection added to AliShuttle::CopyFileLocally
74
7d43a416 75Revision 1.62 2007/10/31 18:23:13 acolla
76Furter developement on the Shuttle:
77
78- Shuttle now connects to the Grid as alidaq. The OCDB and Reference folders
79are now built from /alice/data, e.g.:
80/alice/data/2007/LHC07a/OCDB
81
82the year and LHC period are taken from the Shuttle.
83Raw metadata files are stored by GRP to:
84/alice/data/2007/LHC07a/<runNb>/Raw/RunMetadata.root
85
86- Shuttle sends a mail to DCS experts each time DP retrieval fails.
87
675f64cd 88Revision 1.61 2007/10/30 20:33:51 acolla
89Improved managing of temporary folders, which weren't correctly handled.
90Resolved bug introduced in StoreReferenceFile, which caused SPD preprocessor fail.
91
d524ade6 92Revision 1.60 2007/10/29 18:06:16 acolla
93
94New function StoreRunMetadataFile added to preprocessor and Shuttle interface
95This function can be used by GRP only. It stores raw data tags merged file to the
96raw data folder (e.g. /alice/data/2008/LHC08a/000099999/Raw).
97
98KNOWN ISSUES:
99
1001. Shuttle cannot write to /alice/data/ because it belongs to alidaq. Tag file is stored in /alice/simulation/... for the time being.
1012. Due to a bug in TAlien::Mkdir, the creation of a folder in recursive mode (-p option) does not work. The problem
102has been corrected in the root package on the Shuttle machine.
103
c88ad5db 104Revision 1.59 2007/10/05 12:40:55 acolla
105
106Result error code added to AliDCSClient data members (it was "lost" with the new implementation of TMap* GetAliasValues and GetDPValues).
107
1790d4b7 108Revision 1.58 2007/09/28 15:27:40 acolla
109
110AliDCSClient "multiSplit" option added in the DCS configuration
111in AliDCSMessage: variable MAX_BODY_SIZE set to 500000
112
542b6cc8 113Revision 1.57 2007/09/27 16:53:13 acolla
114Detectors can have more than one AMANDA server. SHUTTLE queries the servers sequentially,
115merges the dcs aliases/DPs in one TMap and sends it to the preprocessor.
116
1d172743 117Revision 1.56 2007/09/14 16:46:14 jgrosseo
1181) Connect and Close are called before and after each query, so one can
119keep the same AliDCSClient object.
1202) The splitting of a query is moved to GetDPValues/GetAliasValues.
1213) Splitting interval can be specified in constructor
122
b41b252a 123Revision 1.55 2007/08/06 12:26:40 acolla
124Function Bool_t GetHLTStatus added to preprocessor. It returns the status of HLT
125read from the run logbook.
126
4859271b 127Revision 1.54 2007/07/12 09:51:25 jgrosseo
128removed duplicated log message in GetFile
129
4f0749a8 130Revision 1.53 2007/07/12 09:26:28 jgrosseo
131updating hlt fxs base path
132
42fde080 133Revision 1.52 2007/07/12 08:06:45 jgrosseo
134adding log messages in getfile... functions
135adding not implemented copy constructor in alishuttleconfigholder
136
1bcd28db 137Revision 1.51 2007/07/03 17:24:52 acolla
138root moved to v5-16-00. TFileMerger->Cp moved to TFile::Cp.
139
a986b218 140Revision 1.50 2007/07/02 17:19:32 acolla
141preprocessor is run in a temp directory that is removed when process is finished.
142
5bac2bde 143Revision 1.49 2007/06/29 10:45:06 acolla
144Number of columns in MySql Shuttle logbook increased by one (HLT added)
145
db99d43e 146Revision 1.48 2007/06/21 13:06:19 acolla
147GetFileSources returns dummy list with 1 source if system=DCS (better than
148returning error as it was)
149
6297b37d 150Revision 1.47 2007/06/19 17:28:56 acolla
151HLT updated; missing map bug removed.
152
dc25836b 153Revision 1.46 2007/06/09 13:01:09 jgrosseo
154Switching to retrieval of several DCS DPs at a time (multiDPrequest)
155
a038aa70 156Revision 1.45 2007/05/30 06:35:20 jgrosseo
157Adding functionality to the Shuttle/TestShuttle:
158o) Function to retrieve list of sources from a given system (GetFileSources with id=0)
159o) Function to retrieve list of IDs for a given source (GetFileIDs)
160These functions are needed for dealing with the tag files that are saved for the GRP preprocessor
161Example code has been added to the TestProcessor in TestShuttle
162
4a33bdd9 163Revision 1.44 2007/05/11 16:09:32 acolla
164Reference files for ITS, MUON and PHOS are now stored in OfflineDetName/OnlineDetName/run_...
165example: ITS/SPD/100_filename.root
166
2d9019b4 167Revision 1.43 2007/05/10 09:59:51 acolla
168Various bug fixes in StoreRefFilesToGrid; Cleaning of reference storage before processing detector (CleanReferenceStorage)
169
546242fb 170Revision 1.42 2007/05/03 08:01:39 jgrosseo
171typo in last commit :-(
172
8b739301 173Revision 1.41 2007/05/03 08:00:48 jgrosseo
174fixing log message when pp want to skip dcs value retrieval
175
651fdaab 176Revision 1.40 2007/04/27 07:06:48 jgrosseo
177GetFileSources returns empty list in case of no files, but successful query
178No mails sent in testmode
179
86aa42c3 180Revision 1.39 2007/04/17 12:43:57 acolla
181Correction in StoreOCDB; change of text in mail to detector expert
182
26758fce 183Revision 1.38 2007/04/12 08:26:18 jgrosseo
184updated comment
185
3c2a21c8 186Revision 1.37 2007/04/10 16:53:14 jgrosseo
187redirecting sub detector stdout, stderr to sub detector log file
188
3d8bc902 189Revision 1.35 2007/04/04 16:26:38 acolla
1901. Re-organization of function calls in TestPreprocessor to make it more meaningful.
1912. Added missing dependency in test preprocessors.
1923. in AliShuttle.cxx: processing time and memory consumption info on a single line.
193
886d60e6 194Revision 1.34 2007/04/04 10:33:36 jgrosseo
1951) Storing of files to the Grid is now done _after_ your preprocessors succeeded. This is transparent, which means that you can still use the same functions (Store, StoreReferenceData) to store files to the Grid. However, the Shuttle first stores them locally and transfers them after the preprocessor finished. The return code of these two functions has changed from UInt_t to Bool_t which gives you the success of the storing.
196In case of an error with the Grid, the Shuttle will retry the storing later, the preprocessor does not need to be run again.
197
1982) The meaning of the return code of the preprocessor has changed. 0 is now success and any other value means failure. This value is stored in the log and you can use it to keep details about the error condition.
199
2003) New function StoreReferenceFile to _directly_ store a file (without opening it) to the reference storage.
201
2024) The memory usage of the preprocessor is monitored. If it exceeds 2 GB it is terminated.
203
2045) New function AliPreprocessor::ProcessDCS(). If you do not need to have DCS data in all cases, you can skip the processing by implemting this function and returning kFALSE under certain conditions. E.g. if there is a certain run type.
205If you always need DCS data (like before), you do not need to implement it.
206
2076) The run type has been added to the monitoring page
208
9827400b 209Revision 1.33 2007/04/03 13:56:01 acolla
210Grid Storage at the end of preprocessing. Added virtual method to disable DCS query according to the
211run type.
212
3301427a 213Revision 1.32 2007/02/28 10:41:56 acolla
214Run type field added in SHUTTLE framework. Run type is read from "run type" logbook and retrieved by
215AliPreprocessor::GetRunType() function.
216Added some ldap definition files.
217
d386d623 218Revision 1.30 2007/02/13 11:23:21 acolla
219Moved getters and setters of Shuttle's main OCDB/Reference, local
220OCDB/Reference, temp and log folders to AliShuttleInterface
221
9d733021 222Revision 1.27 2007/01/30 17:52:42 jgrosseo
223adding monalisa monitoring
224
e7f62f16 225Revision 1.26 2007/01/23 19:20:03 acolla
226Removed old ldif files, added TOF, MCH ldif files. Added some options in
227AliShuttleConfig::Print. Added in Ali Shuttle: SetShuttleTempDir and
228SetShuttleLogDir
229
36c99a6a 230Revision 1.25 2007/01/15 19:13:52 acolla
231Moved some AliInfo to AliDebug in SendMail function
232
fc5a4708 233Revision 1.21 2006/12/07 08:51:26 jgrosseo
234update (alberto):
235table, db names in ldap configuration
236added GRP preprocessor
237DCS data can also be retrieved by data point
238
2c15234c 239Revision 1.20 2006/11/16 16:16:48 jgrosseo
240introducing strict run ordering flag
241removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
242
be48e3ea 243Revision 1.19 2006/11/06 14:23:04 jgrosseo
244major update (Alberto)
245o) reading of run parameters from the logbook
246o) online offline naming conversion
247o) standalone DCSclient package
248
eba76848 249Revision 1.18 2006/10/20 15:22:59 jgrosseo
250o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
251o) Merging Collect, CollectAll, CollectNew function
252o) Removing implementation of empty copy constructors (declaration still there!)
253
cb343cfd 254Revision 1.17 2006/10/05 16:20:55 jgrosseo
255adapting to new CDB classes
256
6ec0e06c 257Revision 1.16 2006/10/05 15:46:26 jgrosseo
258applying to the new interface
259
481441a2 260Revision 1.15 2006/10/02 16:38:39 jgrosseo
261update (alberto):
262fixed memory leaks
263storing of objects that failed to be stored to the grid before
264interfacing of shuttle status table in daq system
265
2bb7b766 266Revision 1.14 2006/08/29 09:16:05 jgrosseo
267small update
268
85a80aa9 269Revision 1.13 2006/08/15 10:50:00 jgrosseo
270effc++ corrections (alberto)
271
4f0ab988 272Revision 1.12 2006/08/08 14:19:29 jgrosseo
273Update to shuttle classes (Alberto)
274
275- Possibility to set the full object's path in the Preprocessor's and
276Shuttle's Store functions
277- Possibility to extend the object's run validity in the same classes
278("startValidity" and "validityInfinite" parameters)
279- Implementation of the StoreReferenceData function to store reference
280data in a dedicated CDB storage.
281
84090f85 282Revision 1.11 2006/07/21 07:37:20 jgrosseo
283last run is stored after each run
284
7bfb2090 285Revision 1.10 2006/07/20 09:54:40 jgrosseo
286introducing status management: The processing per subdetector is divided into several steps,
287after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
288can keep track of the number of failures and skips further processing after a certain threshold is
289exceeded. These thresholds can be configured in LDAP.
290
5164a766 291Revision 1.9 2006/07/19 10:09:55 jgrosseo
292new configuration, accesst to DAQ FES (Alberto)
293
57f50b3c 294Revision 1.8 2006/07/11 12:44:36 jgrosseo
295adding parameters for extended validity range of data produced by preprocessor
296
17111222 297Revision 1.7 2006/07/10 14:37:09 jgrosseo
298small fix + todo comment
299
e090413b 300Revision 1.6 2006/07/10 13:01:41 jgrosseo
301enhanced storing of last sucessfully processed run (alberto)
302
a7160fe9 303Revision 1.5 2006/07/04 14:59:57 jgrosseo
304revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
305
45a493ce 306Revision 1.4 2006/06/12 09:11:16 jgrosseo
307coding conventions (Alberto)
308
58bc3020 309Revision 1.3 2006/06/06 14:26:40 jgrosseo
310o) removed files that were moved to STEER
311o) shuttle updated to follow the new interface (Alberto)
312
b948db8d 313Revision 1.2 2006/03/07 07:52:34 hristov
314New version (B.Yordanov)
315
d477ad88 316Revision 1.6 2005/11/19 17:19:14 byordano
317RetrieveDATEEntries and RetrieveConditionsData added
318
319Revision 1.5 2005/11/19 11:09:27 byordano
320AliShuttle declaration added
321
322Revision 1.4 2005/11/17 17:47:34 byordano
323TList changed to TObjArray
324
325Revision 1.3 2005/11/17 14:43:23 byordano
326import to local CVS
327
328Revision 1.1.1.1 2005/10/28 07:33:58 hristov
329Initial import as subdirectory in AliRoot
330
73abe331 331Revision 1.2 2005/09/13 08:41:15 byordano
332default startTime endTime added
333
334Revision 1.4 2005/08/30 09:13:02 byordano
335some docs added
336
337Revision 1.3 2005/08/29 21:15:47 byordano
338some docs added
339
340*/
341
342//
343// This class is the main manager for AliShuttle.
344// It organizes the data retrieval from DCS and call the
b948db8d 345// interface methods of AliPreprocessor.
73abe331 346// For every detector in AliShuttleConfgi (see AliShuttleConfig),
347// data for its set of aliases is retrieved. If there is registered
b948db8d 348// AliPreprocessor for this detector then it will be used
349// accroding to the schema (see AliPreprocessor).
350// If there isn't registered AliPreprocessor than the retrieved
73abe331 351// data is stored automatically to the undelying AliCDBStorage.
352// For detSpec is used the alias name.
353//
354
355#include "AliShuttle.h"
356
357#include "AliCDBManager.h"
358#include "AliCDBStorage.h"
359#include "AliCDBId.h"
84090f85 360#include "AliCDBRunRange.h"
361#include "AliCDBPath.h"
5164a766 362#include "AliCDBEntry.h"
73abe331 363#include "AliShuttleConfig.h"
eba76848 364#include "DCSClient/AliDCSClient.h"
73abe331 365#include "AliLog.h"
b948db8d 366#include "AliPreprocessor.h"
5164a766 367#include "AliShuttleStatus.h"
2bb7b766 368#include "AliShuttleLogbookEntry.h"
73abe331 369
57f50b3c 370#include <TSystem.h>
58bc3020 371#include <TObject.h>
b948db8d 372#include <TString.h>
57f50b3c 373#include <TTimeStamp.h>
73abe331 374#include <TObjString.h>
57f50b3c 375#include <TSQLServer.h>
376#include <TSQLResult.h>
377#include <TSQLRow.h>
cb343cfd 378#include <TMutex.h>
9827400b 379#include <TSystemDirectory.h>
380#include <TSystemFile.h>
a986b218 381#include <TFile.h>
9827400b 382#include <TGrid.h>
383#include <TGridResult.h>
73abe331 384
e7f62f16 385#include <TMonaLisaWriter.h>
386
5164a766 387#include <fstream>
388
cb343cfd 389#include <sys/types.h>
390#include <sys/wait.h>
391
73abe331 392ClassImp(AliShuttle)
393
b948db8d 394//______________________________________________________________________________________________
395AliShuttle::AliShuttle(const AliShuttleConfig* config,
396 UInt_t timeout, Int_t retries):
4f0ab988 397fConfig(config),
398fTimeout(timeout), fRetries(retries),
399fPreprocessorMap(),
2bb7b766 400fLogbookEntry(0),
eba76848 401fCurrentDetector(),
85a80aa9 402fStatusEntry(0),
cb343cfd 403fMonitoringMutex(0),
eba76848 404fLastActionTime(0),
e7f62f16 405fLastAction(),
9827400b 406fMonaLisa(0),
407fTestMode(kNone),
ffa29e93 408fReadTestMode(kFALSE),
409fOutputRedirected(kFALSE)
73abe331 410{
411 //
412 // config: AliShuttleConfig used
73abe331 413 // timeout: timeout used for AliDCSClient connection
414 // retries: the number of retries in case of connection error.
415 //
416
57f50b3c 417 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
be48e3ea 418 for(int iSys=0;iSys<4;iSys++) {
57f50b3c 419 fServer[iSys]=0;
be48e3ea 420 if (iSys < 3)
2c15234c 421 fFXSlist[iSys].SetOwner(kTRUE);
57f50b3c 422 }
2bb7b766 423 fPreprocessorMap.SetOwner(kTRUE);
be48e3ea 424
425 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
426 fFirstUnprocessed[iDet] = kFALSE;
427
cb343cfd 428 fMonitoringMutex = new TMutex();
58bc3020 429}
430
b948db8d 431//______________________________________________________________________________________________
57f50b3c 432AliShuttle::~AliShuttle()
58bc3020 433{
9827400b 434 //
435 // destructor
436 //
58bc3020 437
b948db8d 438 fPreprocessorMap.DeleteAll();
be48e3ea 439 for(int iSys=0;iSys<4;iSys++)
57f50b3c 440 if(fServer[iSys]) {
441 fServer[iSys]->Close();
442 delete fServer[iSys];
eba76848 443 fServer[iSys] = 0;
57f50b3c 444 }
2bb7b766 445
446 if (fStatusEntry){
447 delete fStatusEntry;
448 fStatusEntry = 0;
449 }
cb343cfd 450
451 if (fMonitoringMutex)
452 {
453 delete fMonitoringMutex;
454 fMonitoringMutex = 0;
455 }
73abe331 456}
457
b948db8d 458//______________________________________________________________________________________________
57f50b3c 459void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
58bc3020 460{
73abe331 461 //
b948db8d 462 // Registers new AliPreprocessor.
73abe331 463 // It uses GetName() for indentificator of the pre processor.
464 // The pre processor is registered it there isn't any other
465 // with the same identificator (GetName()).
466 //
467
eba76848 468 const char* detName = preprocessor->GetName();
469 if(GetDetPos(detName) < 0)
470 AliFatal(Form("********** !!!!! Invalid detector name: %s !!!!! **********", detName));
471
472 if (fPreprocessorMap.GetValue(detName)) {
473 AliWarning(Form("AliPreprocessor %s is already registered!", detName));
73abe331 474 return;
475 }
476
eba76848 477 fPreprocessorMap.Add(new TObjString(detName), preprocessor);
73abe331 478}
b948db8d 479//______________________________________________________________________________________________
3301427a 480Bool_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
84090f85 481 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
73abe331 482{
9827400b 483 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
484 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
485 // using this function. Use StoreReferenceData instead!
486 // It calls StoreLocally function which temporarily stores the data locally; when the preprocessor
487 // finishes the data are transferred to the main storage (Grid).
b948db8d 488
3301427a 489 return StoreLocally(fgkLocalCDB, path, object, metaData, validityStart, validityInfinite);
84090f85 490}
491
492//______________________________________________________________________________________________
3301427a 493Bool_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData)
84090f85 494{
9827400b 495 // Stores a CDB object in the storage for reference data. This objects will not be available during
496 // offline reconstrunction. Use this function for reference data only!
497 // It calls StoreLocally function which temporarily stores the data locally; when the preprocessor
498 // finishes the data are transferred to the main storage (Grid).
85a80aa9 499
3301427a 500 return StoreLocally(fgkLocalRefStorage, path, object, metaData);
85a80aa9 501}
502
503//______________________________________________________________________________________________
3301427a 504Bool_t AliShuttle::StoreLocally(const TString& localUri,
85a80aa9 505 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
506 Int_t validityStart, Bool_t validityInfinite)
507{
9827400b 508 // Store object temporarily in local storage. Parameters are passed by Store and StoreReferenceData functions.
509 // when the preprocessor finishes the data are transferred to the main storage (Grid).
510 // The parameters are:
511 // 1) Uri of the backup storage (Local)
512 // 2) the object's path.
513 // 3) the object to be stored
514 // 4) the metaData to be associated with the object
515 // 5) the validity start run number w.r.t. the current run,
516 // if the data is valid only for this run leave the default 0
517 // 6) specifies if the calibration data is valid for infinity (this means until updated),
518 // typical for calibration runs, the default is kFALSE
519 //
520 // returns 0 if fail, 1 otherwise
84090f85 521
9827400b 522 if (fTestMode & kErrorStorage)
523 {
524 Log(fCurrentDetector, "StoreLocally - In TESTMODE - Simulating error while storing locally");
525 return kFALSE;
526 }
527
3301427a 528 const char* cdbType = (localUri == fgkLocalCDB) ? "CDB" : "Reference";
2bb7b766 529
85a80aa9 530 Int_t firstRun = GetCurrentRun() - validityStart;
84090f85 531 if(firstRun < 0) {
9827400b 532 AliWarning("First valid run happens to be less than 0! Setting it to 0.");
84090f85 533 firstRun=0;
534 }
535
536 Int_t lastRun = -1;
537 if(validityInfinite) {
538 lastRun = AliCDBRunRange::Infinity();
539 } else {
540 lastRun = GetCurrentRun();
541 }
542
3301427a 543 // Version is set to current run, it will be used later to transfer data to Grid
544 AliCDBId id(path, firstRun, lastRun, GetCurrentRun(), -1);
2bb7b766 545
546 if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
547 TObjString runUsed = Form("%d", GetCurrentRun());
9e080f92 548 metaData->SetProperty("RunUsed(TObjString)", runUsed.Clone());
2bb7b766 549 }
84090f85 550
3301427a 551 Bool_t result = kFALSE;
84090f85 552
3301427a 553 if (!(AliCDBManager::Instance()->GetStorage(localUri))) {
554 Log("SHUTTLE", Form("StoreLocally - Cannot activate local %s storage", cdbType));
84090f85 555 } else {
3301427a 556 result = AliCDBManager::Instance()->GetStorage(localUri)
84090f85 557 ->Put(object, id, metaData);
558 }
559
560 if(!result) {
561
9827400b 562 Log(fCurrentDetector, Form("StoreLocally - Can't store object <%s>!", id.ToString().Data()));
3301427a 563 }
2bb7b766 564
3301427a 565 return result;
566}
84090f85 567
3301427a 568//______________________________________________________________________________________________
569Bool_t AliShuttle::StoreOCDB()
570{
9827400b 571 //
572 // Called when preprocessor ends successfully or when previous storage attempt failed (kStoreError status)
573 // Calls underlying StoreOCDB(const char*) function twice, for OCDB and Reference storage.
574 // Then calls StoreRefFilesToGrid to store reference files.
575 //
576
577 if (fTestMode & kErrorGrid)
578 {
579 Log("SHUTTLE", "StoreOCDB - In TESTMODE - Simulating error while storing in the Grid");
580 Log(fCurrentDetector, "StoreOCDB - In TESTMODE - Simulating error while storing in the Grid");
581 return kFALSE;
582 }
583
c88ad5db 584 Log("SHUTTLE","StoreOCDB - Storing OCDB data ...");
86aa42c3 585 Bool_t resultCDB = StoreOCDB(fgkMainCDB);
586
c88ad5db 587 Log("SHUTTLE","StoreOCDB - Storing reference data ...");
3301427a 588 Bool_t resultRef = StoreOCDB(fgkMainRefStorage);
9827400b 589
c88ad5db 590 Log("SHUTTLE","StoreOCDB - Storing reference files ...");
591 Bool_t resultRefFiles = CopyFilesToGrid("reference");
592
593 Bool_t resultMetadata = kTRUE;
594 if(fCurrentDetector == "GRP")
595 {
596 Log("StoreOCDB - SHUTTLE","Storing Run Metadata file ...");
597 resultMetadata = CopyFilesToGrid("metadata");
598 }
9827400b 599
c88ad5db 600 return resultCDB && resultRef && resultRefFiles && resultMetadata;
3301427a 601}
602
603//______________________________________________________________________________________________
604Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
605{
606 //
607 // Called by StoreOCDB(), performs actual storage to the main OCDB and reference storages (Grid)
608 //
609
610 TObjArray* gridIds=0;
611
612 Bool_t result = kTRUE;
613
614 const char* type = 0;
615 TString localURI;
616 if(gridURI == fgkMainCDB) {
617 type = "OCDB";
618 localURI = fgkLocalCDB;
619 } else if(gridURI == fgkMainRefStorage) {
620 type = "reference";
621 localURI = fgkLocalRefStorage;
622 } else {
623 AliError(Form("Invalid storage URI: %s", gridURI.Data()));
624 return kFALSE;
625 }
626
627 AliCDBManager* man = AliCDBManager::Instance();
628
629 AliCDBStorage *gridSto = man->GetStorage(gridURI);
630 if(!gridSto) {
631 Log("SHUTTLE",
632 Form("StoreOCDB - cannot activate main %s storage", type));
633 return kFALSE;
634 }
635
636 gridIds = gridSto->GetQueryCDBList();
637
638 // get objects previously stored in local CDB
639 AliCDBStorage *localSto = man->GetStorage(localURI);
640 if(!localSto) {
641 Log("SHUTTLE",
642 Form("StoreOCDB - cannot activate local %s storage", type));
643 return kFALSE;
644 }
645 AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
646 // Local objects were stored with current run as Grid version!
647 TList* localEntries = localSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
648 localEntries->SetOwner(1);
649
650 // loop on local stored objects
651 TIter localIter(localEntries);
652 AliCDBEntry *aLocEntry = 0;
653 while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
654 aLocEntry->SetOwner(1);
655 AliCDBId aLocId = aLocEntry->GetId();
656 aLocEntry->SetVersion(-1);
657 aLocEntry->SetSubVersion(-1);
658
659 // If local object is valid up to infinity we store it only if it is
660 // the first unprocessed run!
661 if (aLocId.GetLastRun() == AliCDBRunRange::Infinity() &&
662 !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
663 {
664 Log("SHUTTLE", Form("StoreOCDB - %s: object %s has validity infinite but "
665 "there are previous unprocessed runs!",
666 fCurrentDetector.Data(), aLocId.GetPath().Data()));
4508ab8b 667 result = kFALSE;
3301427a 668 continue;
669 }
670
671 // loop on Grid valid Id's
672 Bool_t store = kTRUE;
673 TIter gridIter(gridIds);
674 AliCDBId* aGridId = 0;
675 while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
676 if(aGridId->GetPath() != aLocId.GetPath()) continue;
677 // skip all objects valid up to infinity
678 if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
679 // if we get here, it means there's already some more recent object stored on Grid!
680 store = kFALSE;
681 break;
682 }
683
684 // If we get here, the file can be stored!
685 Bool_t storeOk = gridSto->Put(aLocEntry);
686 if(!store || storeOk){
687
688 if (!store)
689 {
690 Log(fCurrentDetector.Data(),
691 Form("StoreOCDB - A more recent object already exists in %s storage: <%s>",
692 type, aGridId->ToString().Data()));
693 } else {
694 Log("SHUTTLE",
695 Form("StoreOCDB - Object <%s> successfully put into %s storage",
696 aLocId.ToString().Data(), type));
2d9019b4 697 Log(fCurrentDetector.Data(),
698 Form("StoreOCDB - Object <%s> successfully put into %s storage",
699 aLocId.ToString().Data(), type));
3301427a 700 }
84090f85 701
3301427a 702 // removing local filename...
703 TString filename;
704 localSto->IdToFilename(aLocId, filename);
c88ad5db 705 Log("SHUTTLE", Form("StoreOCDB - Removing local file %s", filename.Data()));
3301427a 706 RemoveFile(filename.Data());
707 continue;
708 } else {
709 Log("SHUTTLE",
710 Form("StoreOCDB - Grid %s storage of object <%s> failed",
711 type, aLocId.ToString().Data()));
2d9019b4 712 Log(fCurrentDetector.Data(),
713 Form("StoreOCDB - Grid %s storage of object <%s> failed",
714 type, aLocId.ToString().Data()));
3301427a 715 result = kFALSE;
b948db8d 716 }
717 }
3301427a 718 localEntries->Clear();
2bb7b766 719
b948db8d 720 return result;
3301427a 721}
722
546242fb 723//______________________________________________________________________________________________
724Bool_t AliShuttle::CleanReferenceStorage(const char* detector)
725{
2d9019b4 726 // clears the directory used to store reference files of a given subdetector
546242fb 727
728 AliCDBManager* man = AliCDBManager::Instance();
729 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
2d9019b4 730 TString localBaseFolder = sto->GetBaseFolder();
731
732 TString targetDir = GetRefFilePrefix(localBaseFolder.Data(), detector);
733
d524ade6 734 Log("SHUTTLE", Form("CleanReferenceStorage - Cleaning %s", targetDir.Data()));
2d9019b4 735
736 TString begin;
737 begin.Form("%d_", GetCurrentRun());
738
739 TSystemDirectory* baseDir = new TSystemDirectory("/", targetDir);
740 if (!baseDir)
741 return kTRUE;
742
743 TList* dirList = baseDir->GetListOfFiles();
744 delete baseDir;
745
746 if (!dirList) return kTRUE;
747
748 if (dirList->GetEntries() < 3)
749 {
750 delete dirList;
751 return kTRUE;
752 }
753
754 Int_t nDirs = 0, nDel = 0;
755 TIter dirIter(dirList);
756 TSystemFile* entry = 0;
546242fb 757
2d9019b4 758 Bool_t success = kTRUE;
546242fb 759
2d9019b4 760 while ((entry = dynamic_cast<TSystemFile*> (dirIter.Next())))
761 {
762 if (entry->IsDirectory())
763 continue;
764
765 TString fileName(entry->GetName());
766 if (!fileName.BeginsWith(begin))
767 continue;
768
769 nDirs++;
770
771 // delete file
772 Int_t result = gSystem->Unlink(fileName.Data());
773
774 if (result)
775 {
d524ade6 776 Log("SHUTTLE", Form("CleanReferenceStorage - Could not delete file %s!", fileName.Data()));
2d9019b4 777 success = kFALSE;
778 } else {
779 nDel++;
780 }
781 }
782
783 if(nDirs > 0)
784 Log("SHUTTLE", Form("CleanReferenceStorage - %d (over %d) reference files in folder %s were deleted.",
785 nDel, nDirs, targetDir.Data()));
786
787
788 delete dirList;
789 return success;
790
791
792
793
794
546242fb 795
796 Int_t result = gSystem->GetPathInfo(targetDir, 0, (Long64_t*) 0, 0, 0);
797 if (result == 0)
798 {
799 // delete directory
d524ade6 800 result = gSystem->Exec(Form("rm -rf %s", targetDir.Data()));
546242fb 801 if (result != 0)
802 {
d524ade6 803 Log("SHUTTLE", Form("CleanReferenceStorage - Could not clean directory %s", targetDir.Data()));
546242fb 804 return kFALSE;
805 }
806 }
807
808 result = gSystem->mkdir(targetDir, kTRUE);
809 if (result != 0)
810 {
c88ad5db 811 Log("SHUTTLE", Form("CleanReferenceStorage - Error creating base directory %s", targetDir.Data()));
546242fb 812 return kFALSE;
813 }
814
815 return kTRUE;
816}
817
9827400b 818//______________________________________________________________________________________________
819Bool_t AliShuttle::StoreReferenceFile(const char* detector, const char* localFile, const char* gridFileName)
820{
821 //
3c2a21c8 822 // Stores reference file directly (without opening it). This function stores the file locally.
9827400b 823 //
3c2a21c8 824 // The file is stored under the following location:
825 // <base folder of local reference storage>/<DET>/<RUN#>_<gridFileName>
826 // where <gridFileName> is the second parameter given to the function
827 //
9827400b 828
829 if (fTestMode & kErrorStorage)
830 {
831 Log(fCurrentDetector, "StoreReferenceFile - In TESTMODE - Simulating error while storing locally");
832 return kFALSE;
833 }
834
835 AliCDBManager* man = AliCDBManager::Instance();
836 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
837
838 TString localBaseFolder = sto->GetBaseFolder();
839
d524ade6 840 TString target = GetRefFilePrefix(localBaseFolder.Data(), detector);
841 target.Append(Form("/%d_%s", GetCurrentRun(), gridFileName));
9827400b 842
d524ade6 843 return CopyFileLocally(localFile, target);
c88ad5db 844}
845
846//______________________________________________________________________________________________
847Bool_t AliShuttle::StoreRunMetadataFile(const char* localFile, const char* gridFileName)
848{
849 //
850 // Stores Run metadata file to the Grid, in the run folder
851 //
852 // Only GRP can call this function.
853
854 if (fTestMode & kErrorStorage)
855 {
856 Log(fCurrentDetector, "StoreRunMetaDataFile - In TESTMODE - Simulating error while storing locally");
857 return kFALSE;
858 }
859
860 AliCDBManager* man = AliCDBManager::Instance();
861 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
862
863 TString localBaseFolder = sto->GetBaseFolder();
864
865 // Build Run level folder
955d2abc 866 // folder = /alice/data/year/lhcPeriod/runNb/raw
c88ad5db 867
c88ad5db 868
675f64cd 869 TString lhcPeriod = GetLHCPeriod();
c88ad5db 870 if (lhcPeriod.Length() == 0)
871 {
872 Log("SHUTTLE","StoreRunMetaDataFile - LHCPeriod not found in logbook!");
873 return 0;
874 }
875
955d2abc 876 TString target = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw/%s",
675f64cd 877 localBaseFolder.Data(), GetCurrentYear(),
d524ade6 878 lhcPeriod.Data(), GetCurrentRun(), gridFileName);
c88ad5db 879
d524ade6 880 return CopyFileLocally(localFile, target);
c88ad5db 881}
882
883//______________________________________________________________________________________________
d524ade6 884Bool_t AliShuttle::CopyFileLocally(const char* localFile, const TString& target)
c88ad5db 885{
886 //
887 // Stores file locally. Called by StoreReferenceFile and StoreRunMetadataFile
d524ade6 888 // Files are temporarily stored in the local reference storage. When the preprocessor
889 // finishes, the Shuttle calls CopyFilesToGrid to transfer the files to AliEn
890 // (in reference or run level folders)
c88ad5db 891 //
892
d524ade6 893 TString targetDir(target(0, target.Last('/')));
894
895 //try to open base dir folder, if it does not exist
2d9019b4 896 void* dir = gSystem->OpenDirectory(targetDir.Data());
897 if (dir == NULL) {
898 if (gSystem->mkdir(targetDir.Data(), kTRUE)) {
c88ad5db 899 Log("SHUTTLE", Form("StoreFileLocally - Can't open directory <%s>", targetDir.Data()));
2d9019b4 900 return kFALSE;
901 }
902
903 } else {
904 gSystem->FreeDirectory(dir);
905 }
9827400b 906
7d43a416 907 Int_t result = 0;
908
909 result = gSystem->GetPathInfo(localFile, 0, (Long64_t*) 0, 0, 0);
9827400b 910 if (result)
911 {
c88ad5db 912 Log("SHUTTLE", Form("StoreFileLocally - %s does not exist", localFile));
546242fb 913 return kFALSE;
9827400b 914 }
546242fb 915
7d43a416 916 result = gSystem->GetPathInfo(target, 0, (Long64_t*) 0, 0, 0);
917 if (!result)
918 {
919 Log("SHUTTLE", Form("StoreFileLocally - target file %s already exist, removing...", target.Data()));
920 if (gSystem->Unlink(target.Data()))
921 {
922 Log("SHUTTLE", Form("StoreFileLocally - Could not remove existing target file %s!", target.Data()));
923 return kFALSE;
924 }
925 }
926
9827400b 927 result = gSystem->CopyFile(localFile, target);
928
929 if (result == 0)
930 {
c88ad5db 931 Log("SHUTTLE", Form("StoreFileLocally - File %s stored locally to %s", localFile, target.Data()));
9827400b 932 return kTRUE;
933 }
934 else
935 {
d524ade6 936 Log("SHUTTLE", Form("StoreFileLocally - Could not store file %s to %s! Error code = %d",
546242fb 937 localFile, target.Data(), result));
9827400b 938 return kFALSE;
939 }
c88ad5db 940
941
942
9827400b 943}
944
945//______________________________________________________________________________________________
c88ad5db 946Bool_t AliShuttle::CopyFilesToGrid(const char* type)
9827400b 947{
948 //
c88ad5db 949 // Transfers local files to the Grid. Local files can be reference files
950 // or run metadata file (from GRP only).
9827400b 951 //
c88ad5db 952 // According to the type (ref, metadata) the files are stored under the following location:
953 // ref --> <base folder of reference storage>/<DET>/<RUN#>_<gridFileName>
954 // metadata --> <run data folder>/<MetadataFileName>
86aa42c3 955 //
c88ad5db 956
9827400b 957 AliCDBManager* man = AliCDBManager::Instance();
958 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
959 if (!sto)
960 return kFALSE;
961 TString localBaseFolder = sto->GetBaseFolder();
9827400b 962
c88ad5db 963 TString dir;
964 TString alienDir;
9827400b 965 TString begin;
9827400b 966
c88ad5db 967 if (strcmp(type, "reference") == 0)
968 {
969 dir = GetRefFilePrefix(localBaseFolder.Data(), fCurrentDetector.Data());
970 AliCDBStorage* gridSto = man->GetStorage(fgkMainRefStorage);
971 if (!gridSto)
972 return kFALSE;
973 TString gridBaseFolder = gridSto->GetBaseFolder();
974 alienDir = GetRefFilePrefix(gridBaseFolder.Data(), fCurrentDetector.Data());
975 begin = Form("%d_", GetCurrentRun());
976 }
977 else if (strcmp(type, "metadata") == 0)
978 {
c88ad5db 979
675f64cd 980 TString lhcPeriod = GetLHCPeriod();
c88ad5db 981
982 if (lhcPeriod.Length() == 0)
983 {
984 Log("SHUTTLE","CopyFilesToGrid - LHCPeriod not found in logbook!");
985 return 0;
986 }
987
955d2abc 988 dir = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw",
675f64cd 989 localBaseFolder.Data(), GetCurrentYear(),
c88ad5db 990 lhcPeriod.Data(), GetCurrentRun());
675f64cd 991 alienDir = dir(dir.Index("/alice/data/"), dir.Length());
992
c88ad5db 993 begin = "";
994 }
995 else
996 {
997 Log("SHUTTLE", "CopyFilesToGrid - Unexpected: type label must be reference or metadata!");
998 return kFALSE;
999 }
1000
9827400b 1001 TSystemDirectory* baseDir = new TSystemDirectory("/", dir);
3d8bc902 1002 if (!baseDir)
1003 return kTRUE;
1004
2d9019b4 1005 TList* dirList = baseDir->GetListOfFiles();
1006 delete baseDir;
1007
1008 if (!dirList) return kTRUE;
1009
1010 if (dirList->GetEntries() < 3)
3d8bc902 1011 {
2d9019b4 1012 delete dirList;
9827400b 1013 return kTRUE;
3d8bc902 1014 }
2d9019b4 1015
546242fb 1016 if (!gGrid)
1017 {
c88ad5db 1018 Log("SHUTTLE", "CopyFilesToGrid - Connection to Grid failed: Cannot continue!");
2d9019b4 1019 delete dirList;
546242fb 1020 return kFALSE;
1021 }
1022
2d9019b4 1023 Int_t nDirs = 0, nTransfer = 0;
1024 TIter dirIter(dirList);
1025 TSystemFile* entry = 0;
1026
9827400b 1027 Bool_t success = kTRUE;
3d8bc902 1028 Bool_t first = kTRUE;
9827400b 1029
2d9019b4 1030 while ((entry = dynamic_cast<TSystemFile*> (dirIter.Next())))
1031 {
9827400b 1032 if (entry->IsDirectory())
1033 continue;
1034
1035 TString fileName(entry->GetName());
1036 if (!fileName.BeginsWith(begin))
1037 continue;
1038
2d9019b4 1039 nDirs++;
1040
3d8bc902 1041 if (first)
1042 {
1043 first = kFALSE;
c88ad5db 1044 // check that folder exists, otherwise create it
3d8bc902 1045 TGridResult* result = gGrid->Ls(alienDir.Data(), "a");
1046
1047 if (!result)
2d9019b4 1048 {
1049 delete dirList;
3d8bc902 1050 return kFALSE;
2d9019b4 1051 }
3d8bc902 1052
546242fb 1053 if (!result->GetFileName(1)) // TODO: It looks like element 0 is always 0!!
3d8bc902 1054 {
675f64cd 1055 // TODO It does not work currently! Bug in TAliEn::Mkdir
1056 // TODO Manually fixed in local root v5-16-00
c88ad5db 1057 if (!gGrid->Mkdir(alienDir.Data(),"-p",0))
3d8bc902 1058 {
c88ad5db 1059 Log("SHUTTLE", Form("CopyFilesToGrid - Cannot create directory %s",
3d8bc902 1060 alienDir.Data()));
2d9019b4 1061 delete dirList;
3d8bc902 1062 return kFALSE;
546242fb 1063 } else {
c88ad5db 1064 Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s created", alienDir.Data()));
3d8bc902 1065 }
1066
546242fb 1067 } else {
c88ad5db 1068 Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s found", alienDir.Data()));
3d8bc902 1069 }
1070 }
1071
9827400b 1072 TString fullLocalPath;
1073 fullLocalPath.Form("%s/%s", dir.Data(), fileName.Data());
1074
1075 TString fullGridPath;
1076 fullGridPath.Form("alien://%s/%s", alienDir.Data(), fileName.Data());
1077
a986b218 1078 Bool_t result = TFile::Cp(fullLocalPath, fullGridPath);
9827400b 1079
1080 if (result)
1081 {
c88ad5db 1082 Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s succeeded!",
1083 fullLocalPath.Data(), fullGridPath.Data()));
9827400b 1084 RemoveFile(fullLocalPath);
2d9019b4 1085 nTransfer++;
9827400b 1086 }
1087 else
1088 {
c88ad5db 1089 Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s FAILED!",
1090 fullLocalPath.Data(), fullGridPath.Data()));
9827400b 1091 success = kFALSE;
1092 }
1093 }
2d9019b4 1094
c88ad5db 1095 Log("SHUTTLE", Form("CopyFilesToGrid - %d (over %d) files in folder %s copied to Grid.",
1096 nTransfer, nDirs, dir.Data()));
2d9019b4 1097
1098
1099 delete dirList;
9827400b 1100 return success;
1101}
1102
2d9019b4 1103//______________________________________________________________________________________________
1104const char* AliShuttle::GetRefFilePrefix(const char* base, const char* detector)
1105{
1106 //
1107 // Get folder name of reference files
1108 //
1109
1110 TString offDetStr(GetOfflineDetName(detector));
1111 TString dir;
1112 if (offDetStr == "ITS" || offDetStr == "MUON" || offDetStr == "PHOS")
1113 {
1114 dir.Form("%s/%s/%s", base, offDetStr.Data(), detector);
1115 } else {
1116 dir.Form("%s/%s", base, offDetStr.Data());
1117 }
1118
1119 return dir.Data();
1120
1121
1122}
c88ad5db 1123
3301427a 1124//______________________________________________________________________________________________
1125void AliShuttle::CleanLocalStorage(const TString& uri)
1126{
9827400b 1127 //
1128 // Called in case the preprocessor is declared failed. Remove remaining objects from the local storages.
1129 //
3301427a 1130
1131 const char* type = 0;
1132 if(uri == fgkLocalCDB) {
1133 type = "OCDB";
1134 } else if(uri == fgkLocalRefStorage) {
546242fb 1135 type = "Reference";
3301427a 1136 } else {
1137 AliError(Form("Invalid storage URI: %s", uri.Data()));
1138 return;
1139 }
1140
1141 AliCDBManager* man = AliCDBManager::Instance();
b948db8d 1142
3301427a 1143 // open local storage
1144 AliCDBStorage *localSto = man->GetStorage(uri);
1145 if(!localSto) {
1146 Log("SHUTTLE",
1147 Form("CleanLocalStorage - cannot activate local %s storage", type));
1148 return;
1149 }
1150
1151 TString filename(Form("%s/%s/*/Run*_v%d_s*.root",
546242fb 1152 localSto->GetBaseFolder().Data(), GetOfflineDetName(fCurrentDetector.Data()), GetCurrentRun()));
3301427a 1153
c88ad5db 1154 AliDebug(2, Form("filename = %s", filename.Data()));
3301427a 1155
c88ad5db 1156 Log("SHUTTLE", Form("Removing remaining local files for run %d and detector %s ...",
3301427a 1157 GetCurrentRun(), fCurrentDetector.Data()));
1158
1159 RemoveFile(filename.Data());
1160
1161}
1162
1163//______________________________________________________________________________________________
1164void AliShuttle::RemoveFile(const char* filename)
1165{
9827400b 1166 //
1167 // removes local file
1168 //
3301427a 1169
1170 TString command(Form("rm -f %s", filename));
1171
1172 Int_t result = gSystem->Exec(command.Data());
1173 if(result != 0)
1174 {
1175 Log("SHUTTLE", Form("RemoveFile - %s: Cannot remove file %s!",
1176 fCurrentDetector.Data(), filename));
1177 }
73abe331 1178}
1179
b948db8d 1180//______________________________________________________________________________________________
5164a766 1181AliShuttleStatus* AliShuttle::ReadShuttleStatus()
1182{
9827400b 1183 //
1184 // Reads the AliShuttleStatus from the CDB
1185 //
5164a766 1186
2bb7b766 1187 if (fStatusEntry){
1188 delete fStatusEntry;
1189 fStatusEntry = 0;
1190 }
5164a766 1191
10a5a932 1192 fStatusEntry = AliCDBManager::Instance()->GetStorage(GetLocalCDB())
2bb7b766 1193 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
5164a766 1194
2bb7b766 1195 if (!fStatusEntry) return 0;
1196 fStatusEntry->SetOwner(1);
5164a766 1197
2bb7b766 1198 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
1199 if (!status) {
1200 AliError("Invalid object stored to CDB!");
1201 return 0;
1202 }
5164a766 1203
2bb7b766 1204 return status;
5164a766 1205}
1206
1207//______________________________________________________________________________________________
7bfb2090 1208Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
5164a766 1209{
9827400b 1210 //
1211 // writes the status for one subdetector
1212 //
2bb7b766 1213
1214 if (fStatusEntry){
1215 delete fStatusEntry;
1216 fStatusEntry = 0;
1217 }
5164a766 1218
2bb7b766 1219 Int_t run = GetCurrentRun();
5164a766 1220
2bb7b766 1221 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
5164a766 1222
2bb7b766 1223 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
1224 fStatusEntry->SetOwner(1);
5164a766 1225
2bb7b766 1226 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
7bfb2090 1227
2bb7b766 1228 if (!result) {
3301427a 1229 Log("SHUTTLE", Form("WriteShuttleStatus - Failed for %s, run %d",
1230 fCurrentDetector.Data(), run));
2bb7b766 1231 return kFALSE;
1232 }
e7f62f16 1233
1234 SendMLInfo();
7bfb2090 1235
2bb7b766 1236 return kTRUE;
5164a766 1237}
1238
1239//______________________________________________________________________________________________
1240void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
1241{
9827400b 1242 //
1243 // changes the AliShuttleStatus for the given detector and run to the given status
1244 //
5164a766 1245
2bb7b766 1246 if (!fStatusEntry){
1247 AliError("UNEXPECTED: fStatusEntry empty");
1248 return;
1249 }
5164a766 1250
2bb7b766 1251 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
5164a766 1252
2bb7b766 1253 if (!status){
c88ad5db 1254 Log("SHUTTLE", "UpdateShuttleStatus - UNEXPECTED: status could not be read from current CDB entry");
2bb7b766 1255 return;
1256 }
5164a766 1257
2c15234c 1258 TString actionStr = Form("UpdateShuttleStatus - %s: Changing state from %s to %s",
eba76848 1259 fCurrentDetector.Data(),
36c99a6a 1260 status->GetStatusName(),
eba76848 1261 status->GetStatusName(newStatus));
cb343cfd 1262 Log("SHUTTLE", actionStr);
1263 SetLastAction(actionStr);
5164a766 1264
2bb7b766 1265 status->SetStatus(newStatus);
1266 if (increaseCount) status->IncreaseCount();
5164a766 1267
2bb7b766 1268 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
e7f62f16 1269
1270 SendMLInfo();
5164a766 1271}
e7f62f16 1272
1273//______________________________________________________________________________________________
1274void AliShuttle::SendMLInfo()
1275{
1276 //
1277 // sends ML information about the current status of the current detector being processed
1278 //
1279
1280 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
1281
1282 if (!status){
3301427a 1283 Log("SHUTTLE", "SendMLInfo - UNEXPECTED: status could not be read from current CDB entry");
e7f62f16 1284 return;
1285 }
1286
1287 TMonaLisaText mlStatus(Form("%s_status", fCurrentDetector.Data()), status->GetStatusName());
1288 TMonaLisaValue mlRetryCount(Form("%s_count", fCurrentDetector.Data()), status->GetCount());
1289
1290 TList mlList;
1291 mlList.Add(&mlStatus);
1292 mlList.Add(&mlRetryCount);
1293
ee6f7523 1294 TString mlID;
1295 mlID.Form("%d", GetCurrentRun());
1296 fMonaLisa->SendParameters(&mlList, mlID);
e7f62f16 1297}
1298
5164a766 1299//______________________________________________________________________________________________
1300Bool_t AliShuttle::ContinueProcessing()
1301{
9827400b 1302 // this function reads the AliShuttleStatus information from CDB and
1303 // checks if the processing should be continued
1304 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
2bb7b766 1305
57c1a579 1306 if (!fConfig->HostProcessDetector(fCurrentDetector)) return kFALSE;
1307
1308 AliPreprocessor* aPreprocessor =
1309 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
1310 if (!aPreprocessor)
1311 {
c88ad5db 1312 Log("SHUTTLE", Form("ContinueProcessing - %s: no preprocessor registered", fCurrentDetector.Data()));
57c1a579 1313 return kFALSE;
1314 }
1315
2bb7b766 1316 AliShuttleLogbookEntry::Status entryStatus =
eba76848 1317 fLogbookEntry->GetDetectorStatus(fCurrentDetector);
2bb7b766 1318
1319 if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
c88ad5db 1320 Log("SHUTTLE", Form("ContinueProcessing - %s is %s",
2bb7b766 1321 fCurrentDetector.Data(),
1322 fLogbookEntry->GetDetectorStatusName(entryStatus)));
1323 return kFALSE;
1324 }
1325
1326 // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
be48e3ea 1327
1328 // check if current run is first unprocessed run for current detector
1329 if (fConfig->StrictRunOrder(fCurrentDetector) &&
1330 !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
1331 {
86aa42c3 1332 if (fTestMode == kNone)
1333 {
c88ad5db 1334 Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering"
1335 " but this is not the first unprocessed run!"));
86aa42c3 1336 return kFALSE;
1337 }
1338 else
1339 {
c88ad5db 1340 Log("SHUTTLE", Form("ContinueProcessing - In TESTMODE - "
1341 "Although %s requires strict run ordering "
1342 "and this is not the first unprocessed run, "
1343 "the SHUTTLE continues"));
86aa42c3 1344 }
be48e3ea 1345 }
1346
2bb7b766 1347 AliShuttleStatus* status = ReadShuttleStatus();
1348 if (!status) {
1349 // first time
1350 Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
1351 fCurrentDetector.Data()));
1352 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
1353 return WriteShuttleStatus(status);
1354 }
1355
1356 // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
1357 // If it happens it may mean Logbook updating failed... let's do it now!
1358 if (status->GetStatus() == AliShuttleStatus::kDone ||
1359 status->GetStatus() == AliShuttleStatus::kFailed){
1360 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
1361 fCurrentDetector.Data(),
1362 status->GetStatusName(status->GetStatus())));
1363 UpdateShuttleLogbook(fCurrentDetector.Data(),
1364 status->GetStatusName(status->GetStatus()));
1365 return kFALSE;
1366 }
1367
3301427a 1368 if (status->GetStatus() == AliShuttleStatus::kStoreError) {
2bb7b766 1369 Log("SHUTTLE",
c88ad5db 1370 Form("ContinueProcessing - %s: Grid storage of one or more "
1371 "objects failed. Trying again now",
2bb7b766 1372 fCurrentDetector.Data()));
9827400b 1373 UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
1374 if (StoreOCDB()){
c88ad5db 1375 Log("SHUTTLE", Form("ContinueProcessing - %s: all objects "
1376 "successfully stored into main storage",
3301427a 1377 fCurrentDetector.Data()));
2bb7b766 1378 } else {
1379 Log("SHUTTLE",
1380 Form("ContinueProcessing - %s: Grid storage failed again",
1381 fCurrentDetector.Data()));
9827400b 1382 UpdateShuttleStatus(AliShuttleStatus::kStoreError);
2bb7b766 1383 }
1384 return kFALSE;
1385 }
1386
1387 // if we get here, there is a restart
57c1a579 1388 Bool_t cont = kFALSE;
2bb7b766 1389
1390 // abort conditions
cb343cfd 1391 if (status->GetCount() >= fConfig->GetMaxRetries()) {
57c1a579 1392 Log("SHUTTLE", Form("ContinueProcessing - %s failed %d times in status %s - "
1393 "Updating Shuttle Logbook", fCurrentDetector.Data(),
2bb7b766 1394 status->GetCount(), status->GetStatusName()));
1395 UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
e7f62f16 1396 UpdateShuttleStatus(AliShuttleStatus::kFailed);
3301427a 1397
1398 // there may still be objects in local OCDB and reference storage
1399 // and FXS databases may be not updated: do it now!
9827400b 1400
1401 // TODO Currently disabled, we want to keep files in case of failure!
1402 // CleanLocalStorage(fgkLocalCDB);
1403 // CleanLocalStorage(fgkLocalRefStorage);
1404 // UpdateTableFailCase();
1405
1406 // Send mail to detector expert!
c88ad5db 1407 Log("SHUTTLE", Form("ContinueProcessing - Sending mail to %s expert...",
1408 fCurrentDetector.Data()));
9827400b 1409 if (!SendMail())
1410 Log("SHUTTLE", Form("ContinueProcessing - Could not send mail to %s expert",
1411 fCurrentDetector.Data()));
3301427a 1412
57c1a579 1413 } else {
1414 Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. "
1415 "Aborted before with %s. Retry number %d.", fCurrentDetector.Data(),
1416 status->GetStatusName(), status->GetCount()));
9827400b 1417 Bool_t increaseCount = kTRUE;
c88ad5db 1418 if (status->GetStatus() == AliShuttleStatus::kDCSError ||
1419 status->GetStatus() == AliShuttleStatus::kDCSStarted)
1420 increaseCount = kFALSE;
675f64cd 1421
9827400b 1422 UpdateShuttleStatus(AliShuttleStatus::kStarted, increaseCount);
57c1a579 1423 cont = kTRUE;
2bb7b766 1424 }
1425
57c1a579 1426 return cont;
5164a766 1427}
1428
1429//______________________________________________________________________________________________
2bb7b766 1430Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
58bc3020 1431{
73abe331 1432 //
b948db8d 1433 // Makes data retrieval for all detectors in the configuration.
2bb7b766 1434 // entry: Shuttle logbook entry, contains run paramenters and status of detectors
1435 // (Unprocessed, Inactive, Failed or Done).
d477ad88 1436 // Returns kFALSE in case of error occured and kTRUE otherwise
73abe331 1437 //
1438
9827400b 1439 if (!entry) return kFALSE;
2bb7b766 1440
1441 fLogbookEntry = entry;
1442
c88ad5db 1443 Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^*",
9827400b 1444 GetCurrentRun()));
2bb7b766 1445
e7f62f16 1446 // Send the information to ML
1447 TMonaLisaText mlStatus("SHUTTLE_status", "Processing");
9827400b 1448 TMonaLisaText mlRunType("SHUTTLE_runtype", Form("%s (%s)", entry->GetRunType(), entry->GetRunParameter("log")));
e7f62f16 1449
1450 TList mlList;
1451 mlList.Add(&mlStatus);
9827400b 1452 mlList.Add(&mlRunType);
e7f62f16 1453
ee6f7523 1454 TString mlID;
1455 mlID.Form("%d", GetCurrentRun());
1456 fMonaLisa->SendParameters(&mlList, mlID);
3301427a 1457
9827400b 1458 if (fLogbookEntry->IsDone())
1459 {
1460 Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
1461 UpdateShuttleLogbook("shuttle_done");
1462 fLogbookEntry = 0;
1463 return kTRUE;
1464 }
1465
1466 // read test mode if flag is set
1467 if (fReadTestMode)
1468 {
3d8bc902 1469 fTestMode = kNone;
9827400b 1470 TString logEntry(entry->GetRunParameter("log"));
1471 //printf("log entry = %s\n", logEntry.Data());
1472 TString searchStr("Testmode: ");
1473 Int_t pos = logEntry.Index(searchStr.Data());
1474 //printf("%d\n", pos);
1475 if (pos >= 0)
1476 {
1477 TSubString subStr = logEntry(pos + searchStr.Length(), logEntry.Length());
1478 //printf("%s\n", subStr.String().Data());
1479 TString newStr(subStr.Data());
1480 TObjArray* token = newStr.Tokenize(' ');
1481 if (token)
1482 {
1483 //token->Print();
1484 TObjString* tmpStr = dynamic_cast<TObjString*> (token->First());
1485 if (tmpStr)
1486 {
1487 Int_t testMode = tmpStr->String().Atoi();
1488 if (testMode > 0)
1489 {
c88ad5db 1490 Log("SHUTTLE", Form("Process - Enabling test mode %d", testMode));
9827400b 1491 SetTestMode((TestMode) testMode);
1492 }
1493 }
1494 delete token;
1495 }
1496 }
1497 }
c88ad5db 1498
eba76848 1499 fLogbookEntry->Print("all");
57f50b3c 1500
1501 // Initialization
d477ad88 1502 Bool_t hasError = kFALSE;
5164a766 1503
675f64cd 1504 // Set the CDB and Reference folders according to the year and LHC period
1505 TString lhcPeriod(GetLHCPeriod());
1506 if (lhcPeriod.Length() == 0)
1507 {
7d4cf768 1508 Log("SHUTTLE","Process - LHCPeriod not found in logbook!");
1509 return 0;
675f64cd 1510 }
1511
1512 if (fgkMainCDB.Length() == 0)
1513 fgkMainCDB = Form("alien://folder=/alice/data/%d/%s/OCDB?user=alidaq?cacheFold=/tmp/OCDBCache",
1514 GetCurrentYear(), lhcPeriod.Data());
1515
1516 if (fgkMainRefStorage.Length() == 0)
1517 fgkMainRefStorage = Form("alien://folder=/alice/data/%d/%s/Reference?user=alidaq?cacheFold=/tmp/OCDBCache",
1518 GetCurrentYear(), lhcPeriod.Data());
1519
57f50b3c 1520 // Loop on detectors in the configuration
b948db8d 1521 TIter iter(fConfig->GetDetectors());
2bb7b766 1522 TObjString* aDetector = 0;
b948db8d 1523
4508ab8b 1524 Bool_t first = kTRUE;
1525
be48e3ea 1526 while ((aDetector = (TObjString*) iter.Next()))
1527 {
7bfb2090 1528 fCurrentDetector = aDetector->String();
5164a766 1529
9e080f92 1530 if (ContinueProcessing() == kFALSE) continue;
4508ab8b 1531
1532 if (first)
1533 {
1534 // only read QueryCDB when needed and only once
1535 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
1536 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
1537 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
1538 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
1539 first = kFALSE;
1540 }
9e080f92 1541
c88ad5db 1542 Log("SHUTTLE", Form("\t\t\t****** run %d - %s: START ******",
2bb7b766 1543 GetCurrentRun(), aDetector->GetName()));
1544
9d733021 1545 for(Int_t iSys=0;iSys<3;iSys++) fFXSCalled[iSys]=kFALSE;
1546
c88ad5db 1547 Log(fCurrentDetector.Data(), "Process - Starting processing");
85a80aa9 1548
be48e3ea 1549 Int_t pid = fork();
1550
1551 if (pid < 0)
1552 {
c88ad5db 1553 Log("SHUTTLE", "Process - ERROR: Forking failed");
be48e3ea 1554 }
1555 else if (pid > 0)
1556 {
1557 // parent
c88ad5db 1558 Log("SHUTTLE", Form("Process - In parent process of %d - %s: Starting monitoring",
be48e3ea 1559 GetCurrentRun(), aDetector->GetName()));
1560
1561 Long_t begin = time(0);
1562
1563 int status; // to be used with waitpid, on purpose an int (not Int_t)!
1564 while (waitpid(pid, &status, WNOHANG) == 0)
1565 {
1566 Long_t expiredTime = time(0) - begin;
1567
1568 if (expiredTime > fConfig->GetPPTimeOut())
1569 {
9827400b 1570 TString tmp;
c88ad5db 1571 tmp.Form("Process - Process of %s time out. "
1572 "Run time: %d seconds. Killing...",
1573 fCurrentDetector.Data(), expiredTime);
9827400b 1574 Log("SHUTTLE", tmp);
1575 Log(fCurrentDetector, tmp);
be48e3ea 1576
1577 kill(pid, 9);
1578
3301427a 1579 UpdateShuttleStatus(AliShuttleStatus::kPPTimeOut);
be48e3ea 1580 hasError = kTRUE;
1581
1582 gSystem->Sleep(1000);
1583 }
1584 else
1585 {
be48e3ea 1586 gSystem->Sleep(1000);
9827400b 1587
1588 TString checkStr;
1589 checkStr.Form("ps -o vsize --pid %d | tail -n 1", pid);
1590 FILE* pipe = gSystem->OpenPipe(checkStr, "r");
1591 if (!pipe)
1592 {
c88ad5db 1593 Log("SHUTTLE", Form("Process - Error: "
1594 "Could not open pipe to %s", checkStr.Data()));
9827400b 1595 continue;
1596 }
1597
1598 char buffer[100];
1599 if (!fgets(buffer, 100, pipe))
1600 {
c88ad5db 1601 Log("SHUTTLE", "Process - Error: ps did not return anything");
9827400b 1602 gSystem->ClosePipe(pipe);
1603 continue;
1604 }
1605 gSystem->ClosePipe(pipe);
1606
1607 //Log("SHUTTLE", Form("ps returned %s", buffer));
1608
1609 Int_t mem = 0;
1610 if ((sscanf(buffer, "%d\n", &mem) != 1) || !mem)
1611 {
c88ad5db 1612 Log("SHUTTLE", "Process - Error: Could not parse output of ps");
9827400b 1613 continue;
1614 }
1615
1616 if (expiredTime % 60 == 0)
ee6f7523 1617 {
c88ad5db 1618 Log("SHUTTLE", Form("Process - %s: Checking process. "
1619 "Run time: %d seconds - Memory consumption: %d KB",
1620 fCurrentDetector.Data(), expiredTime, mem));
ee6f7523 1621 SendAlive();
1622 }
9827400b 1623
1624 if (mem > fConfig->GetPPMaxMem())
1625 {
1626 TString tmp;
c88ad5db 1627 tmp.Form("Process - Process exceeds maximum allowed memory "
1628 "(%d KB > %d KB). Killing...",
9827400b 1629 mem, fConfig->GetPPMaxMem());
1630 Log("SHUTTLE", tmp);
1631 Log(fCurrentDetector, tmp);
1632
1633 kill(pid, 9);
1634
1635 UpdateShuttleStatus(AliShuttleStatus::kPPOutOfMemory);
1636 hasError = kTRUE;
1637
1638 gSystem->Sleep(1000);
1639 }
be48e3ea 1640 }
1641 }
1642
c88ad5db 1643 Log("SHUTTLE", Form("Process - In parent process of %d - %s: Client has terminated.",
be48e3ea 1644 GetCurrentRun(), aDetector->GetName()));
1645
1646 if (WIFEXITED(status))
1647 {
1648 Int_t returnCode = WEXITSTATUS(status);
1649
c88ad5db 1650 Log("SHUTTLE", Form("Process - %s: the return code is %d", fCurrentDetector.Data(),
3301427a 1651 returnCode));
be48e3ea 1652
9827400b 1653 if (returnCode == 0) hasError = kTRUE;
be48e3ea 1654 }
1655 }
1656 else if (pid == 0)
1657 {
1658 // client
c88ad5db 1659 Log("SHUTTLE", Form("Process - In client process of %d - %s", GetCurrentRun(),
1660 aDetector->GetName()));
be48e3ea 1661
c88ad5db 1662 Log("SHUTTLE", Form("Process - Redirecting output to %s log",fCurrentDetector.Data()));
ffa29e93 1663
546242fb 1664 if ((freopen(GetLogFileName(fCurrentDetector), "a", stdout)) == 0)
ffa29e93 1665 {
c88ad5db 1666 Log("SHUTTLE", "Process - Could not freopen stdout");
ffa29e93 1667 }
1668 else
1669 {
1670 fOutputRedirected = kTRUE;
1671 if ((dup2(fileno(stdout), fileno(stderr))) < 0)
c88ad5db 1672 Log("SHUTTLE", "Process - Could not redirect stderr");
ffa29e93 1673
1674 }
1675
5bac2bde 1676 TString wd = gSystem->WorkingDirectory();
675f64cd 1677 TString tmpDir = Form("%s/%s_%d_process", GetShuttleTempDir(),
1678 fCurrentDetector.Data(), GetCurrentRun());
5bac2bde 1679
d524ade6 1680 Int_t result = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0);
1681 if (!result) // temp dir already exists!
1682 {
1683 Log(fCurrentDetector.Data(),
1684 Form("Process - %s dir already exists! Removing...", tmpDir.Data()));
1685 gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));
675f64cd 1686 }
1687
1688 if (gSystem->mkdir(tmpDir.Data(), 1))
1689 {
1690 Log(fCurrentDetector.Data(), "Process - could not make temp directory!!");
1691 gSystem->Exit(1);
d524ade6 1692 }
1693
1694 if (!gSystem->ChangeDirectory(tmpDir.Data()))
1695 {
1696 Log(fCurrentDetector.Data(), "Process - could not change directory!!");
1697 gSystem->Exit(1);
1698 }
5bac2bde 1699
9827400b 1700 Bool_t success = ProcessCurrentDetector();
5bac2bde 1701
1702 gSystem->ChangeDirectory(wd.Data());
b1d18693 1703
9827400b 1704 if (success) // Preprocessor finished successfully!
1705 {
b1d18693 1706 // remove temporary folder
fbc112e3 1707 // temporary commented (JF)
1708 //gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));
b1d18693 1709
3301427a 1710 // Update time_processed field in FXS DB
1711 if (UpdateTable() == kFALSE)
5bac2bde 1712 Log("SHUTTLE", Form("Process - %s: Could not update FXS databases!",
1713 fCurrentDetector.Data()));
3301427a 1714
1715 // Transfer the data from local storage to main storage (Grid)
1716 UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
1717 if (StoreOCDB() == kFALSE)
1718 {
c88ad5db 1719 Log("SHUTTLE",
1720 Form("\t\t\t****** run %d - %s: STORAGE ERROR ******",
3301427a 1721 GetCurrentRun(), aDetector->GetName()));
1722 UpdateShuttleStatus(AliShuttleStatus::kStoreError);
9827400b 1723 success = kFALSE;
3301427a 1724 } else {
c88ad5db 1725 Log("SHUTTLE",
1726 Form("\t\t\t****** run %d - %s: DONE ******",
3301427a 1727 GetCurrentRun(), aDetector->GetName()));
1728 UpdateShuttleStatus(AliShuttleStatus::kDone);
9827400b 1729 UpdateShuttleLogbook(fCurrentDetector, "DONE");
3301427a 1730 }
c88ad5db 1731 } else
1732 {
1733 Log("SHUTTLE",
1734 Form("\t\t\t****** run %d - %s: PP ERROR ******",
1735 GetCurrentRun(), aDetector->GetName()));
be48e3ea 1736 }
1737
4b95672b 1738 for (UInt_t iSys=0; iSys<3; iSys++)
1739 {
1740 if (fFXSCalled[iSys]) fFXSlist[iSys].Clear();
1741 }
1742
c88ad5db 1743 Log("SHUTTLE", Form("Process - Client process of %d - %s is exiting now with %d.",
9827400b 1744 GetCurrentRun(), aDetector->GetName(), success));
be48e3ea 1745
1746 // the client exits here
9827400b 1747 gSystem->Exit(success);
be48e3ea 1748
1749 AliError("We should never get here!!!");
1750 }
7bfb2090 1751 }
5164a766 1752
c88ad5db 1753 Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^*",
2bb7b766 1754 GetCurrentRun()));
1755
1756 //check if shuttle is done for this run, if so update logbook
1757 TObjArray checkEntryArray;
1758 checkEntryArray.SetOwner(1);
9e080f92 1759 TString whereClause = Form("where run=%d", GetCurrentRun());
b0e53b15 1760 if (!QueryShuttleLogbook(whereClause.Data(), checkEntryArray) ||
1761 checkEntryArray.GetEntries() == 0) {
9e080f92 1762 Log("SHUTTLE", Form("Process - Warning: Cannot check status of run %d on Shuttle logbook!",
1763 GetCurrentRun()));
1764 return hasError == kFALSE;
1765 }
b948db8d 1766
9e080f92 1767 AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
1768 (checkEntryArray.At(0));
2bb7b766 1769
9e080f92 1770 if (checkEntry)
1771 {
1772 if (checkEntry->IsDone())
be48e3ea 1773 {
9e080f92 1774 Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
1775 UpdateShuttleLogbook("shuttle_done");
1776 }
1777 else
1778 {
1779 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
be48e3ea 1780 {
9e080f92 1781 if (checkEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
be48e3ea 1782 {
9e080f92 1783 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
1784 checkEntry->GetRun(), GetDetName(iDet)));
1785 fFirstUnprocessed[iDet] = kFALSE;
be48e3ea 1786 }
1787 }
2bb7b766 1788 }
1789 }
1790
1791 fLogbookEntry = 0;
85a80aa9 1792
a7160fe9 1793 return hasError == kFALSE;
73abe331 1794}
1795
b948db8d 1796//______________________________________________________________________________________________
9827400b 1797Bool_t AliShuttle::ProcessCurrentDetector()
73abe331 1798{
1799 //
2bb7b766 1800 // Makes data retrieval just for a specific detector (fCurrentDetector).
73abe331 1801 // Threre should be a configuration for this detector.
73abe331 1802
1d172743 1803 Log("SHUTTLE", Form("ProcessCurrentDetector - Retrieving values for %s, run %d",
1804 fCurrentDetector.Data(), GetCurrentRun()));
73abe331 1805
d524ade6 1806 TString wd = gSystem->WorkingDirectory();
1807
2d9019b4 1808 if (!CleanReferenceStorage(fCurrentDetector.Data()))
546242fb 1809 return kFALSE;
d524ade6 1810
1811 gSystem->ChangeDirectory(wd.Data());
1812
1d172743 1813 TMap* dcsMap = new TMap();
3301427a 1814
1815 // call preprocessor
1816 AliPreprocessor* aPreprocessor =
1817 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
1818
1819 aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
1820
1821 Bool_t processDCS = aPreprocessor->ProcessDCS();
d477ad88 1822
651fdaab 1823 if (!processDCS)
1824 {
1d172743 1825 Log(fCurrentDetector, "ProcessCurrentDetector -"
1826 " The preprocessor requested to skip the retrieval of DCS values");
651fdaab 1827 }
8b739301 1828 else if (fTestMode & kSkipDCS)
2c15234c 1829 {
1d172743 1830 Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Skipping DCS processing");
9827400b 1831 }
1832 else if (fTestMode & kErrorDCS)
1833 {
1d172743 1834 Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Simulating DCS error");
3d8bc902 1835 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
9827400b 1836 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
1d172743 1837 delete dcsMap;
9827400b 1838 return kFALSE;
2c15234c 1839 } else {
3301427a 1840
1841 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
1842
1d172743 1843 // Query DCS archive
1844 Int_t nServers = fConfig->GetNServers(fCurrentDetector);
a038aa70 1845
1d172743 1846 for (int iServ=0; iServ<nServers; iServ++)
2c15234c 1847 {
1d172743 1848
1849 TString host(fConfig->GetDCSHost(fCurrentDetector, iServ));
1850 Int_t port = fConfig->GetDCSPort(fCurrentDetector, iServ);
542b6cc8 1851 Int_t multiSplit = fConfig->GetMultiSplit(fCurrentDetector, iServ);
1852
1790d4b7 1853 Log(fCurrentDetector, Form("ProcessCurrentDetector -"
1854 " Querying DCS Amanda server %s:%d (%d of %d)",
1855 host.Data(), port, iServ+1, nServers));
1d172743 1856
1857 TMap* aliasMap = 0;
1858 TMap* dpMap = 0;
1859
1860 if (fConfig->GetDCSAliases(fCurrentDetector, iServ)->GetEntries() > 0)
2c15234c 1861 {
1d172743 1862 aliasMap = GetValueSet(host, port,
542b6cc8 1863 fConfig->GetDCSAliases(fCurrentDetector, iServ),
1864 kAlias, multiSplit);
1d172743 1865 if (!aliasMap)
1866 {
1867 Log(fCurrentDetector,
1868 Form("ProcessCurrentDetector -"
675f64cd 1869 " Error retrieving DCS aliases from server %s."
1870 " Sending mail to DCS experts!", host.Data()));
1d172743 1871 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
675f64cd 1872
b5f1c82e 1873 //if (!SendMailToDCS())
1874 // Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
675f64cd 1875
a038aa70 1876 delete dcsMap;
1d172743 1877 return kFALSE;
1878 }
2c15234c 1879 }
a038aa70 1880
1d172743 1881 if (fConfig->GetDCSDataPoints(fCurrentDetector, iServ)->GetEntries() > 0)
a038aa70 1882 {
1d172743 1883 dpMap = GetValueSet(host, port,
542b6cc8 1884 fConfig->GetDCSDataPoints(fCurrentDetector, iServ),
1885 kDP, multiSplit);
1d172743 1886 if (!dpMap)
1887 {
1888 Log(fCurrentDetector,
1889 Form("ProcessCurrentDetector -"
675f64cd 1890 " Error retrieving DCS data points from server %s."
1891 " Sending mail to DCS experts!", host.Data()));
1d172743 1892 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
675f64cd 1893
b5f1c82e 1894 //if (!SendMailToDCS())
1895 // Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
675f64cd 1896
1d172743 1897 if (aliasMap) delete aliasMap;
1898 delete dcsMap;
1899 return kFALSE;
1900 }
a038aa70 1901 }
1d172743 1902
1903 // merge aliasMap and dpMap into dcsMap
1904 if(aliasMap) {
1905 TIter iter(aliasMap);
a038aa70 1906 TObjString* key = 0;
1907 while ((key = (TObjString*) iter.Next()))
1d172743 1908 dcsMap->Add(key, aliasMap->GetValue(key->String()));
1909
1910 aliasMap->SetOwner(kFALSE);
1911 delete aliasMap;
1912 }
1913
1914 if(dpMap) {
1915 TIter iter(dpMap);
1916 TObjString* key = 0;
1917 while ((key = (TObjString*) iter.Next()))
1918 dcsMap->Add(key, dpMap->GetValue(key->String()));
1919
1920 dpMap->SetOwner(kFALSE);
1921 delete dpMap;
a038aa70 1922 }
73abe331 1923 }
1924 }
dc25836b 1925
b1d18693 1926 // save map into file, to help debugging in case of preprocessor error
fbc112e3 1927 TFile* f = TFile::Open("DCSMap.root","recreate");
b1d18693 1928 f->cd();
1929 dcsMap->Write("DCSMap", TObject::kSingleKey);
1930 f->Close();
fbc112e3 1931 delete f;
b1d18693 1932
2bb7b766 1933 // DCS Archive DB processing successful. Call Preprocessor!
85a80aa9 1934 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
a7160fe9 1935
a038aa70 1936 UInt_t returnValue = aPreprocessor->Process(dcsMap);
b948db8d 1937
3301427a 1938 if (returnValue > 0) // Preprocessor error!
1939 {
c88ad5db 1940 Log(fCurrentDetector, Form("ProcessCurrentDetector - "
1941 "Preprocessor failed. Process returned %d.", returnValue));
cb343cfd 1942 UpdateShuttleStatus(AliShuttleStatus::kPPError);
a038aa70 1943 dcsMap->DeleteAll();
1944 delete dcsMap;
9827400b 1945 return kFALSE;
1946 }
1947
1948 // preprocessor ok!
1949 UpdateShuttleStatus(AliShuttleStatus::kPPDone);
1950 Log(fCurrentDetector, Form("ProcessCurrentDetector - %s preprocessor returned success",
1951 fCurrentDetector.Data()));
b948db8d 1952
a038aa70 1953 dcsMap->DeleteAll();
1954 delete dcsMap;
b948db8d 1955
9827400b 1956 return kTRUE;
2bb7b766 1957}
1958
fbc112e3 1959//______________________________________________________________________________________________
1960void AliShuttle::CountOpenRuns()
1961{
1962 // Query DAQ's Shuttle logbook and sends the number of open runs to ML
1963
1964 // check connection, in case connect
1965 if (!Connect(3))
1966 return;
1967
1968 TString sqlQuery;
1969 sqlQuery = Form("select count(*) from %s where shuttle_done=0", fConfig->GetShuttlelbTable());
1970
1971 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
1972 if (!aResult) {
1973 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
1974 return;
1975 }
1976
1977 AliDebug(2,Form("Query = %s", sqlQuery.Data()));
1978
1979 if (aResult->GetRowCount() == 0) {
1980 AliError(Form("No result for query %s received", sqlQuery.Data()));
1981 return;
1982 }
1983
1984 if (aResult->GetFieldCount() != 1) {
1985 AliError(Form("Invalid field count for query %s received", sqlQuery.Data()));
1986 return;
1987 }
1988
1989 TSQLRow* aRow = aResult->Next();
1990 if (!aRow) {
1991 AliError(Form("Could not receive result of query %s", sqlQuery.Data()));
1992 return;
1993 }
1994
1995 TString result(aRow->GetField(0), aRow->GetFieldLength(0));
1996 Int_t count = result.Atoi();
1997
1998 Log("SHUTTLE", Form("%d unprocessed runs", count));
1999
2000 delete aRow;
2001 delete aResult;
2002
2003 TMonaLisaValue mlStatus("SHUTTLE_openruns", count);
2004
2005 TList mlList;
2006 mlList.Add(&mlStatus);
2007
2008 fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__");
2009}
2010
2bb7b766 2011//______________________________________________________________________________________________
2012Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
2013 TObjArray& entries)
2014{
9827400b 2015 // Query DAQ's Shuttle logbook and fills detector status object.
2016 // Call QueryRunParameters to query DAQ logbook for run parameters.
2017 //
2bb7b766 2018
fc5a4708 2019 entries.SetOwner(1);
2020
2bb7b766 2021 // check connection, in case connect
fbc112e3 2022 if (!Connect(3)) return kFALSE;
2bb7b766 2023
2024 TString sqlQuery;
441b0e9c 2025 sqlQuery = Form("select * from %s %s order by run", fConfig->GetShuttlelbTable(), whereClause);
2bb7b766 2026
be48e3ea 2027 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
2bb7b766 2028 if (!aResult) {
2029 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
2030 return kFALSE;
2031 }
2032
fc5a4708 2033 AliDebug(2,Form("Query = %s", sqlQuery.Data()));
2034
2bb7b766 2035 if(aResult->GetRowCount() == 0) {
c88ad5db 2036 Log("SHUTTLE", "No entries in Shuttle Logbook match request");
9827400b 2037 delete aResult;
2038 return kTRUE;
2bb7b766 2039 }
2040
2041 // TODO Check field count!
db99d43e 2042 const UInt_t nCols = 23;
2bb7b766 2043 if (aResult->GetFieldCount() != (Int_t) nCols) {
c88ad5db 2044 Log("SHUTTLE", "Invalid SQL result field number!");
2bb7b766 2045 delete aResult;
2046 return kFALSE;
2047 }
2048
2bb7b766 2049 TSQLRow* aRow;
2050 while ((aRow = aResult->Next())) {
2051 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
2052 Int_t run = runString.Atoi();
2053
eba76848 2054 AliShuttleLogbookEntry *entry = QueryRunParameters(run);
2055 if (!entry)
2056 continue;
2bb7b766 2057
2058 // loop on detectors
eba76848 2059 for(UInt_t ii = 0; ii < nCols; ii++)
2060 entry->SetDetectorStatus(aResult->GetFieldName(ii), aRow->GetField(ii));
2bb7b766 2061
eba76848 2062 entries.AddLast(entry);
2bb7b766 2063 delete aRow;
2064 }
2065
2bb7b766 2066 delete aResult;
2067 return kTRUE;
2068}
2069
2070//______________________________________________________________________________________________
eba76848 2071AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
2bb7b766 2072{
eba76848 2073 //
2074 // Retrieve run parameters written in the DAQ logbook and sets them into AliShuttleLogbookEntry object
2075 //
2bb7b766 2076
2077 // check connection, in case connect
be48e3ea 2078 if (!Connect(3))
eba76848 2079 return 0;
2bb7b766 2080
2081 TString sqlQuery;
2c15234c 2082 sqlQuery.Form("select * from %s where run=%d", fConfig->GetDAQlbTable(), run);
2bb7b766 2083
be48e3ea 2084 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
2bb7b766 2085 if (!aResult) {
c88ad5db 2086 Log("SHUTTLE", Form("Can't execute query <%s>!", sqlQuery.Data()));
eba76848 2087 return 0;
2bb7b766 2088 }
2089
eba76848 2090 if (aResult->GetRowCount() == 0) {
2bb7b766 2091 Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
2092 delete aResult;
eba76848 2093 return 0;
2bb7b766 2094 }
2095
eba76848 2096 if (aResult->GetRowCount() > 1) {
c88ad5db 2097 Log("SHUTTLE", Form("QueryRunParameters - UNEXPECTED: "
2098 "more than one entry in DAQ Logbook for run %d!", run));
2bb7b766 2099 delete aResult;
eba76848 2100 return 0;
2bb7b766 2101 }
2102
eba76848 2103 TSQLRow* aRow = aResult->Next();
2104 if (!aRow)
2105 {
c88ad5db 2106 Log("SHUTTLE", Form("QueryRunParameters - Could not retrieve row for run %d. Skipping", run));
eba76848 2107 delete aResult;
2108 return 0;
2109 }
2bb7b766 2110
eba76848 2111 AliShuttleLogbookEntry* entry = new AliShuttleLogbookEntry(run);
2bb7b766 2112
eba76848 2113 for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
2114 entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
2bb7b766 2115
eba76848 2116 UInt_t startTime = entry->GetStartTime();
2117 UInt_t endTime = entry->GetEndTime();
2118
1abfbb60 2119// if (!startTime || !endTime || startTime > endTime)
2120// {
2121// Log("SHUTTLE",
2122// Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d. Skipping!",
2123// run, startTime, endTime));
2124//
2125// Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2126// fLogbookEntry = entry;
2127// if (!UpdateShuttleLogbook("shuttle_done"))
2128// {
2129// AliError(Form("Could not update logbook for run %d !", run));
2130// }
2131// fLogbookEntry = 0;
2132//
2133// delete entry;
2134// delete aRow;
2135// delete aResult;
2136// return 0;
2137// }
2138
2139 if (!startTime)
b0e53b15 2140 {
2141 Log("SHUTTLE",
1abfbb60 2142 Form("QueryRunParameters - Invalid parameters for Run %d: "
2143 "startTime = %d, endTime = %d. Skipping!",
2144 run, startTime, endTime));
b0e53b15 2145
2146 Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2147 fLogbookEntry = entry;
ee6f7523 2148 if (!UpdateShuttleLogbook("shuttle_ignored"))
b0e53b15 2149 {
2150 AliError(Form("Could not update logbook for run %d !", run));
2151 }
2152 fLogbookEntry = 0;
2153
2154 delete entry;
2155 delete aRow;
2156 delete aResult;
2157 return 0;
2158 }
2159
1abfbb60 2160 if (startTime && !endTime)
2161 {
2162 // TODO Here we don't mark SHUTTLE done, because this may mean
2163 //the run is still ongoing!!
2164 Log("SHUTTLE",
2165 Form("QueryRunParameters - Invalid parameters for Run %d: "
2166 "startTime = %d, endTime = %d. Skipping (Shuttle won't be marked as DONE)!",
2167 run, startTime, endTime));
2168
2169 //Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2170 //fLogbookEntry = entry;
2171 //if (!UpdateShuttleLogbook("shuttle_done"))
2172 //{
2173 // AliError(Form("Could not update logbook for run %d !", run));
2174 //}
2175 //fLogbookEntry = 0;
2176
2177 delete entry;
2178 delete aRow;
2179 delete aResult;
2180 return 0;
2181 }
2182
2183 if (startTime && endTime && (startTime > endTime))
2184 {
2185 Log("SHUTTLE",
2186 Form("QueryRunParameters - Invalid parameters for Run %d: "
2187 "startTime = %d, endTime = %d. Skipping!",
2188 run, startTime, endTime));
2189
2190 Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2191 fLogbookEntry = entry;
ee6f7523 2192 if (!UpdateShuttleLogbook("shuttle_ignored"))
1abfbb60 2193 {
2194 AliError(Form("Could not update logbook for run %d !", run));
2195 }
2196 fLogbookEntry = 0;
2197
2198 delete entry;
2199 delete aRow;
2200 delete aResult;
2201 return 0;
2202 }
2203
b0e53b15 2204 TString totEventsStr = entry->GetRunParameter("totalEvents");
2205 Int_t totEvents = totEventsStr.Atoi();
2206 if (totEvents < 1)
2207 {
eba76848 2208 Log("SHUTTLE",
b0e53b15 2209 Form("QueryRunParameters - Run %d has 0 events - Skipping!", run));
2210
2211 Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2212 fLogbookEntry = entry;
97e3c167 2213 if (!UpdateShuttleLogbook("shuttle_ignored"))
b0e53b15 2214 {
2215 AliError(Form("Could not update logbook for run %d !", run));
2216 }
2217 fLogbookEntry = 0;
2218
eba76848 2219 delete entry;
2bb7b766 2220 delete aRow;
eba76848 2221 delete aResult;
2222 return 0;
2bb7b766 2223 }
2224
eba76848 2225 delete aRow;
2bb7b766 2226 delete aResult;
eba76848 2227
2228 return entry;
2bb7b766 2229}
2230
a038aa70 2231//______________________________________________________________________________________________
2232TMap* AliShuttle::GetValueSet(const char* host, Int_t port, const TSeqCollection* entries,
542b6cc8 2233 DCSType type, Int_t multiSplit)
a038aa70 2234{
2235 // Retrieve all "entry" data points from the DCS server
2236 // host, port: TSocket connection parameters
2237 // entries: list of name of the alias or data point
2238 // type: kAlias or kDP
2239 // returns TMap of values, 0 when failure
542b6cc8 2240
2241 AliDCSClient client(host, port, fTimeout, fRetries, multiSplit);
b41b252a 2242
a038aa70 2243 TMap* result = 0;
b41b252a 2244 if (type == kAlias)
a038aa70 2245 {
b41b252a 2246 result = client.GetAliasValues(entries, GetCurrentStartTime(),
2247 GetCurrentEndTime());
2248 }
2249 else if (type == kDP)
2250 {
2251 result = client.GetDPValues(entries, GetCurrentStartTime(),
2252 GetCurrentEndTime());
2253 }
a038aa70 2254
b41b252a 2255 if (result == 0)
2256 {
2257 Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get entries! Reason: %s",
1790d4b7 2258 client.GetErrorString(client.GetResultErrorCode())));
2259 if (client.GetResultErrorCode() == AliDCSClient::fgkServerError)
2260 Log(fCurrentDetector.Data(), Form("GetValueSet - Server error code: %s",
2261 client.GetServerError().Data()));
a038aa70 2262
b41b252a 2263 return 0;
a038aa70 2264 }
b41b252a 2265
a038aa70 2266 return result;
2267}
b41b252a 2268
b948db8d 2269//______________________________________________________________________________________________
57f50b3c 2270const char* AliShuttle::GetFile(Int_t system, const char* detector,
2271 const char* id, const char* source)
b948db8d 2272{
9827400b 2273 // Get calibration file from file exchange servers
2274 // First queris the FXS database for the file name, using the run, detector, id and source info
2275 // then calls RetrieveFile(filename) for actual copy to local disk
2276 // run: current run being processed (given by Logbook entry fLogbookEntry)
2277 // detector: the Preprocessor name
2278 // id: provided as a parameter by the Preprocessor
2279 // source: provided by the Preprocessor through GetFileSources function
2280
2281 // check if test mode should simulate a FXS error
2282 if (fTestMode & kErrorFXSFiles)
2283 {
2284 Log(detector, Form("GetFile - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
2285 return 0;
2286 }
2287
57f50b3c 2288 // check connection, in case connect
9d733021 2289 if (!Connect(system))
eba76848 2290 {
9d733021 2291 Log(detector, Form("GetFile - Couldn't connect to %s FXS database", GetSystemName(system)));
57f50b3c 2292 return 0;
2293 }
2294
2295 // Query preparation
9d733021 2296 TString sourceName(source);
d386d623 2297 Int_t nFields = 3;
2298 TString sqlQueryStart = Form("select filePath,size,fileChecksum from %s where",
2299 fConfig->GetFXSdbTable(system));
2300 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
2301 GetCurrentRun(), detector, id);
2302
9d733021 2303 if (system == kDAQ)
2304 {
d386d623 2305 whereClause += Form(" and DAQsource=\"%s\"", source);
57f50b3c 2306 }
9d733021 2307 else if (system == kDCS)
eba76848 2308 {
9d733021 2309 sourceName="none";
57f50b3c 2310 }
9d733021 2311 else if (system == kHLT)
9e080f92 2312 {
d386d623 2313 whereClause += Form(" and DDLnumbers=\"%s\"", source);
9d733021 2314 nFields = 3;
9e080f92 2315 }
2316
9e080f92 2317 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
2318
2319 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2320
2321 // Query execution
2322 TSQLResult* aResult = 0;
9d733021 2323 aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
9e080f92 2324 if (!aResult) {
9d733021 2325 Log(detector, Form("GetFileName - Can't execute SQL query to %s database for: id = %s, source = %s",
2326 GetSystemName(system), id, sourceName.Data()));
9e080f92 2327 return 0;
2328 }
2329
2330 if(aResult->GetRowCount() == 0)
2331 {
2332 Log(detector,
9d733021 2333 Form("GetFileName - No entry in %s FXS db for: id = %s, source = %s",
2334 GetSystemName(system), id, sourceName.Data()));
9e080f92 2335 delete aResult;
2336 return 0;
2337 }
2bb7b766 2338
9e080f92 2339 if (aResult->GetRowCount() > 1) {
2340 Log(detector,
9d733021 2341 Form("GetFileName - More than one entry in %s FXS db for: id = %s, source = %s",
2342 GetSystemName(system), id, sourceName.Data()));
9e080f92 2343 delete aResult;
2344 return 0;
2345 }
2346
9d733021 2347 if (aResult->GetFieldCount() != nFields) {
9e080f92 2348 Log(detector,
9d733021 2349 Form("GetFileName - Wrong field count in %s FXS db for: id = %s, source = %s",
2350 GetSystemName(system), id, sourceName.Data()));
9e080f92 2351 delete aResult;
2352 return 0;
2353 }
2354
2355 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
2356
2357 if (!aRow){
9d733021 2358 Log(detector, Form("GetFileName - Empty set result in %s FXS db from query: id = %s, source = %s",
2359 GetSystemName(system), id, sourceName.Data()));
9e080f92 2360 delete aResult;
2361 return 0;
2362 }
2363
2364 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
2365 TString fileSize(aRow->GetField(1), aRow->GetFieldLength(1));
d386d623 2366 TString fileChecksum(aRow->GetField(2), aRow->GetFieldLength(2));
9e080f92 2367
2368 delete aResult;
2369 delete aRow;
2370
d386d623 2371 AliDebug(2, Form("filePath = %s; size = %s, fileChecksum = %s",
2372 filePath.Data(), fileSize.Data(), fileChecksum.Data()));
9e080f92 2373
9e080f92 2374 // retrieved file is renamed to make it unique
675f64cd 2375 TString localFileName = Form("%s/%s_%d_process/%s_%s_%d_%s_%s.shuttle",
2376 GetShuttleTempDir(), detector, GetCurrentRun(),
d524ade6 2377 GetSystemName(system), detector, GetCurrentRun(),
2378 id, sourceName.Data());
9d733021 2379
9e080f92 2380
9d733021 2381 // file retrieval from FXS
4b95672b 2382 UInt_t nRetries = 0;
2383 UInt_t maxRetries = 3;
2384 Bool_t result = kFALSE;
2385
2386 // copy!! if successful TSystem::Exec returns 0
2387 while(nRetries++ < maxRetries) {
2388 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
2389 result = RetrieveFile(system, filePath.Data(), localFileName.Data());
2390 if(!result)
2391 {
2392 Log(detector, Form("GetFileName - Copy of file %s from %s FXS failed",
9d733021 2393 filePath.Data(), GetSystemName(system)));
4b95672b 2394 continue;
4f0749a8 2395 }
9e080f92 2396
d386d623 2397 if (fileChecksum.Length()>0)
4b95672b 2398 {
2399 // compare md5sum of local file with the one stored in the FXS DB
d524ade6 2400 Int_t md5Comp = gSystem->Exec(Form("md5sum %s |grep %s 2>&1 > /dev/null",
2401 localFileName.Data(), fileChecksum.Data()));
9e080f92 2402
4b95672b 2403 if (md5Comp != 0)
2404 {
2405 Log(detector, Form("GetFileName - md5sum of file %s does not match with local copy!",
2406 filePath.Data()));
2407 result = kFALSE;
2408 continue;
2409 }
d386d623 2410 } else {
2411 Log(fCurrentDetector, Form("GetFile - md5sum of file %s not set in %s database, skipping comparison",
2412 filePath.Data(), GetSystemName(system)));
9d733021 2413 }
4b95672b 2414 if (result) break;
9e080f92 2415 }
2416
4b95672b 2417 if(!result) return 0;
2418
9d733021 2419 fFXSCalled[system]=kTRUE;
2420 TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, sourceName.Data()));
2421 fFXSlist[system].Add(fileParams);
9e080f92 2422
675f64cd 2423 static TString staticLocalFileName;
2424 staticLocalFileName.Form("%s", localFileName.Data());
2425
c88ad5db 2426 Log(fCurrentDetector, Form("GetFile - Retrieved file with id %s and "
2427 "source %s from %s to %s", id, source,
d524ade6 2428 GetSystemName(system), localFileName.Data()));
675f64cd 2429
d524ade6 2430 return staticLocalFileName.Data();
2bb7b766 2431}
2432
2433//______________________________________________________________________________________________
9d733021 2434Bool_t AliShuttle::RetrieveFile(UInt_t system, const char* fxsFileName, const char* localFileName)
9e080f92 2435{
9827400b 2436 //
2437 // Copies file from FXS to local Shuttle machine
2438 //
2bb7b766 2439
9e080f92 2440 // check temp directory: trying to cd to temp; if it does not exist, create it
d524ade6 2441 AliDebug(2, Form("Copy file %s from %s FXS into %s",
2442 GetSystemName(system), fxsFileName, localFileName));
2443
2444 TString tmpDir(localFileName);
2445
2446 tmpDir = tmpDir(0,tmpDir.Last('/'));
9e080f92 2447
d524ade6 2448 Int_t noDir = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0);
2449 if (noDir) // temp dir does not exists!
2450 {
2451 if (gSystem->mkdir(tmpDir.Data(), 1))
2452 {
2453 Log(fCurrentDetector.Data(), "RetrieveFile - could not make temp directory!!");
9e080f92 2454 return kFALSE;
2455 }
9e080f92 2456 }
2457
9d733021 2458 TString baseFXSFolder;
2459 if (system == kDAQ)
2460 {
2461 baseFXSFolder = "FES/";
2462 }
2463 else if (system == kDCS)
2464 {
2465 baseFXSFolder = "";
2466 }
2467 else if (system == kHLT)
2468 {
42fde080 2469 baseFXSFolder = "/opt/FXS/";
9d733021 2470 }
2471
2472
d524ade6 2473 TString command = Form("scp -oPort=%d -2 %s@%s:%s%s %s",
9d733021 2474 fConfig->GetFXSPort(system),
2475 fConfig->GetFXSUser(system),
2476 fConfig->GetFXSHost(system),
2477 baseFXSFolder.Data(),
2478 fxsFileName,
9e080f92 2479 localFileName);
2480
2481 AliDebug(2, Form("%s",command.Data()));
2482
4b95672b 2483 Bool_t result = (gSystem->Exec(command.Data()) == 0);
9e080f92 2484
4b95672b 2485 return result;
9e080f92 2486}
2487
2488//______________________________________________________________________________________________
9d733021 2489TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
2490{
9827400b 2491 //
2492 // Get sources producing the condition file Id from file exchange servers
4a33bdd9 2493 // if id is NULL all sources are returned (distinct)
9827400b 2494 //
1bcd28db 2495
2496 Log(detector, Form("GetFileSources - Retrieving sources with id %s from %s", id, GetSystemName(system)));
9827400b 2497
2498 // check if test mode should simulate a FXS error
2499 if (fTestMode & kErrorFXSSources)
2500 {
2501 Log(detector, Form("GetFileSources - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
2502 return 0;
2503 }
2504
9d733021 2505 if (system == kDCS)
2506 {
c88ad5db 2507 Log(detector, "GetFileSources - WARNING: DCS system has only one source of data!");
6297b37d 2508 TList *list = new TList();
2509 list->SetOwner(1);
2510 list->Add(new TObjString(" "));
2511 return list;
9d733021 2512 }
9e080f92 2513
2514 // check connection, in case connect
9d733021 2515 if (!Connect(system))
2516 {
4a33bdd9 2517 Log(detector, Form("GetFileSources - Couldn't connect to %s FXS database", GetSystemName(system)));
9d733021 2518 return NULL;
9e080f92 2519 }
2520
9d733021 2521 TString sourceName = 0;
2522 if (system == kDAQ)
2523 {
2524 sourceName = "DAQsource";
2525 } else if (system == kHLT)
2526 {
2527 sourceName = "DDLnumbers";
2528 }
2529
4a33bdd9 2530 TString sqlQueryStart = Form("select distinct %s from %s where", sourceName.Data(), fConfig->GetFXSdbTable(system));
2531 TString whereClause = Form("run=%d and detector=\"%s\"",
2532 GetCurrentRun(), detector);
2533 if (id)
2534 whereClause += Form(" and fileId=\"%s\"", id);
9e080f92 2535 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
2536
2537 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2538
2539 // Query execution
2540 TSQLResult* aResult;
9d733021 2541 aResult = fServer[system]->Query(sqlQuery);
9e080f92 2542 if (!aResult) {
9d733021 2543 Log(detector, Form("GetFileSources - Can't execute SQL query to %s database for id: %s",
2544 GetSystemName(system), id));
9e080f92 2545 return 0;
2546 }
2547
86aa42c3 2548 TList *list = new TList();
2549 list->SetOwner(1);
2550
9d733021 2551 if (aResult->GetRowCount() == 0)
2552 {
9e080f92 2553 Log(detector,
9d733021 2554 Form("GetFileSources - No entry in %s FXS table for id: %s", GetSystemName(system), id));
9e080f92 2555 delete aResult;
86aa42c3 2556 return list;
9e080f92 2557 }
2558
1bcd28db 2559 Log(detector, Form("GetFileSources - Found %d sources", aResult->GetRowCount()));
9e080f92 2560
1bcd28db 2561 TSQLRow* aRow;
9d733021 2562 while ((aRow = aResult->Next()))
2563 {
9e080f92 2564
9d733021 2565 TString source(aRow->GetField(0), aRow->GetFieldLength(0));
2566 AliDebug(2, Form("%s = %s", sourceName.Data(), source.Data()));
2567 list->Add(new TObjString(source));
9e080f92 2568 delete aRow;
2569 }
9d733021 2570
9e080f92 2571 delete aResult;
2572
2573 return list;
2bb7b766 2574}
2575
4a33bdd9 2576//______________________________________________________________________________________________
2577TList* AliShuttle::GetFileIDs(Int_t system, const char* detector, const char* source)
2578{
2579 //
2580 // Get all ids of condition files produced by a given source from file exchange servers
2581 //
2582
1bcd28db 2583 Log(detector, Form("GetFileIDs - Retrieving ids with source %s with %s", source, GetSystemName(system)));
2584
4a33bdd9 2585 // check if test mode should simulate a FXS error
2586 if (fTestMode & kErrorFXSSources)
2587 {
2588 Log(detector, Form("GetFileIDs - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
2589 return 0;
2590 }
2591
2592 // check connection, in case connect
2593 if (!Connect(system))
2594 {
2595 Log(detector, Form("GetFileIDs - Couldn't connect to %s FXS database", GetSystemName(system)));
2596 return NULL;
2597 }
2598
2599 TString sourceName = 0;
2600 if (system == kDAQ)
2601 {
2602 sourceName = "DAQsource";
2603 } else if (system == kHLT)
2604 {
2605 sourceName = "DDLnumbers";
2606 }
2607
2608 TString sqlQueryStart = Form("select fileId from %s where", fConfig->GetFXSdbTable(system));
2609 TString whereClause = Form("run=%d and detector=\"%s\"",
2610 GetCurrentRun(), detector);
2611 if (sourceName.Length() > 0 && source)
2612 whereClause += Form(" and %s=\"%s\"", sourceName.Data(), source);
2613 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
2614
2615 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2616
2617 // Query execution
2618 TSQLResult* aResult;
2619 aResult = fServer[system]->Query(sqlQuery);
2620 if (!aResult) {
2621 Log(detector, Form("GetFileIDs - Can't execute SQL query to %s database for source: %s",
2622 GetSystemName(system), source));
2623 return 0;
2624 }
2625
2626 TList *list = new TList();
2627 list->SetOwner(1);
2628
2629 if (aResult->GetRowCount() == 0)
2630 {
2631 Log(detector,
2632 Form("GetFileIDs - No entry in %s FXS table for source: %s", GetSystemName(system), source));
2633 delete aResult;
2634 return list;
2635 }
2636
1bcd28db 2637 Log(detector, Form("GetFileIDs - Found %d ids", aResult->GetRowCount()));
2638
4a33bdd9 2639 TSQLRow* aRow;
2640
2641 while ((aRow = aResult->Next()))
2642 {
2643
2644 TString id(aRow->GetField(0), aRow->GetFieldLength(0));
2645 AliDebug(2, Form("fileId = %s", id.Data()));
2646 list->Add(new TObjString(id));
2647 delete aRow;
2648 }
2649
2650 delete aResult;
2651
2652 return list;
2653}
2654
2bb7b766 2655//______________________________________________________________________________________________
9d733021 2656Bool_t AliShuttle::Connect(Int_t system)
2bb7b766 2657{
9827400b 2658 // Connect to MySQL Server of the system's FXS MySQL databases
2659 // DAQ Logbook, Shuttle Logbook and DAQ FXS db are on the same host
2660 //
57f50b3c 2661
9d733021 2662 // check connection: if already connected return
2663 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
57f50b3c 2664
9d733021 2665 TString dbHost, dbUser, dbPass, dbName;
57f50b3c 2666
9d733021 2667 if (system < 3) // FXS db servers
2668 {
2669 dbHost = Form("mysql://%s:%d", fConfig->GetFXSdbHost(system), fConfig->GetFXSdbPort(system));
2670 dbUser = fConfig->GetFXSdbUser(system);
2671 dbPass = fConfig->GetFXSdbPass(system);
2672 dbName = fConfig->GetFXSdbName(system);
2673 } else { // Run & Shuttle logbook servers
2674 // TODO Will the Shuttle logbook server be the same as the Run logbook server ???
2675 dbHost = Form("mysql://%s:%d", fConfig->GetDAQlbHost(), fConfig->GetDAQlbPort());
2676 dbUser = fConfig->GetDAQlbUser();
2677 dbPass = fConfig->GetDAQlbPass();
2678 dbName = fConfig->GetDAQlbDB();
2679 }
57f50b3c 2680
9d733021 2681 fServer[system] = TSQLServer::Connect(dbHost.Data(), dbUser.Data(), dbPass.Data());
2682 if (!fServer[system] || !fServer[system]->IsConnected()) {
2683 if(system < 3)
2684 {
2685 AliError(Form("Can't establish connection to FXS database for %s",
2686 AliShuttleInterface::GetSystemName(system)));
2687 } else {
2688 AliError("Can't establish connection to Run logbook.");
57f50b3c 2689 }
9d733021 2690 if(fServer[system]) delete fServer[system];
2691 return kFALSE;
2bb7b766 2692 }
57f50b3c 2693
9d733021 2694 // Get tables
2695 TSQLResult* aResult=0;
2696 switch(system){
2697 case kDAQ:
2698 aResult = fServer[kDAQ]->GetTables(dbName.Data());
2699 break;
2700 case kDCS:
2701 aResult = fServer[kDCS]->GetTables(dbName.Data());
2702 break;
2703 case kHLT:
2704 aResult = fServer[kHLT]->GetTables(dbName.Data());
2705 break;
2706 default:
2707 aResult = fServer[3]->GetTables(dbName.Data());
2708 break;
2709 }
2710
2711 delete aResult;
2bb7b766 2712 return kTRUE;
2713}
57f50b3c 2714
9e080f92 2715//______________________________________________________________________________________________
9d733021 2716Bool_t AliShuttle::UpdateTable()
9e080f92 2717{
9827400b 2718 //
2719 // Update FXS table filling time_processed field in all rows corresponding to current run and detector
2720 //
9e080f92 2721
9d733021 2722 Bool_t result = kTRUE;
9e080f92 2723
9d733021 2724 for (UInt_t system=0; system<3; system++)
2725 {
2726 if(!fFXSCalled[system]) continue;
9e080f92 2727
9d733021 2728 // check connection, in case connect
2729 if (!Connect(system))
2730 {
2731 Log(fCurrentDetector, Form("UpdateTable - Couldn't connect to %s FXS database", GetSystemName(system)));
2732 result = kFALSE;
2733 continue;
9e080f92 2734 }
9e080f92 2735
9d733021 2736 TTimeStamp now; // now
2737
2738 // Loop on FXS list entries
2739 TIter iter(&fFXSlist[system]);
2740 TObjString *aFXSentry=0;
2741 while ((aFXSentry = dynamic_cast<TObjString*> (iter.Next())))
2742 {
2743 TString aFXSentrystr = aFXSentry->String();
2744 TObjArray *aFXSarray = aFXSentrystr.Tokenize("#!?!#");
2745 if (!aFXSarray || aFXSarray->GetEntries() != 2 )
2746 {
2747 Log(fCurrentDetector, Form("UpdateTable - error updating %s FXS entry. Check string: <%s>",
2748 GetSystemName(system), aFXSentrystr.Data()));
2749 if(aFXSarray) delete aFXSarray;
2750 result = kFALSE;
2751 continue;
2752 }
2753 const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
2754 const char* source = ((TObjString*) aFXSarray->At(1))->GetName();
2755
2756 TString whereClause;
2757 if (system == kDAQ)
2758 {
2759 whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
2760 GetCurrentRun(), fCurrentDetector.Data(), fileId, source);
2761 }
2762 else if (system == kDCS)
2763 {
2764 whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\";",
2765 GetCurrentRun(), fCurrentDetector.Data(), fileId);
2766 }
2767 else if (system == kHLT)
2768 {
2769 whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DDLnumbers=\"%s\";",
2770 GetCurrentRun(), fCurrentDetector.Data(), fileId, source);
2771 }
2772
2773 delete aFXSarray;
9e080f92 2774
9d733021 2775 TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(system),
2776 now.GetSec(), whereClause.Data());
9e080f92 2777
9d733021 2778 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
9e080f92 2779
9d733021 2780 // Query execution
2781 TSQLResult* aResult;
2782 aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
2783 if (!aResult)
2784 {
2785 Log(fCurrentDetector, Form("UpdateTable - %s db: can't execute SQL query <%s>",
2786 GetSystemName(system), sqlQuery.Data()));
2787 result = kFALSE;
2788 continue;
2789 }
2790 delete aResult;
9e080f92 2791 }
9e080f92 2792 }
2793
9d733021 2794 return result;
9e080f92 2795}
57f50b3c 2796
3301427a 2797//______________________________________________________________________________________________
2798Bool_t AliShuttle::UpdateTableFailCase()
2799{
9827400b 2800 // Update FXS table filling time_processed field in all rows corresponding to current run and detector
2801 // this is called in case the preprocessor is declared failed for the current run, because
2802 // the fields are updated only in case of success
3301427a 2803
2804 Bool_t result = kTRUE;
2805
2806 for (UInt_t system=0; system<3; system++)
2807 {
2808 // check connection, in case connect
2809 if (!Connect(system))
2810 {
2811 Log(fCurrentDetector, Form("UpdateTableFailCase - Couldn't connect to %s FXS database",
2812 GetSystemName(system)));
2813 result = kFALSE;
2814 continue;
2815 }
2816
2817 TTimeStamp now; // now
2818
2819 // Loop on FXS list entries
2820
2821 TString whereClause = Form("where run=%d and detector=\"%s\";",
2822 GetCurrentRun(), fCurrentDetector.Data());
2823
2824
2825 TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(system),
2826 now.GetSec(), whereClause.Data());
2827
2828 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2829
2830 // Query execution
2831 TSQLResult* aResult;
2832 aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
2833 if (!aResult)
2834 {
2835 Log(fCurrentDetector, Form("UpdateTableFailCase - %s db: can't execute SQL query <%s>",
2836 GetSystemName(system), sqlQuery.Data()));
2837 result = kFALSE;
2838 continue;
2839 }
2840 delete aResult;
2841 }
2842
2843 return result;
2844}
2845
2bb7b766 2846//______________________________________________________________________________________________
2847Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
2848{
e7f62f16 2849 //
2850 // Update Shuttle logbook filling detector or shuttle_done column
2851 // ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
2852 //
57f50b3c 2853
2bb7b766 2854 // check connection, in case connect
be48e3ea 2855 if(!Connect(3)){
2bb7b766 2856 Log("SHUTTLE", "UpdateShuttleLogbook - Couldn't connect to DAQ Logbook.");
2857 return kFALSE;
57f50b3c 2858 }
2859
2bb7b766 2860 TString detName(detector);
2861 TString setClause;
ee6f7523 2862 if (detName == "shuttle_done" || detName == "shuttle_ignored")
e7f62f16 2863 {
2bb7b766 2864 setClause = "set shuttle_done=1";
e7f62f16 2865
ee6f7523 2866 if (detName == "shuttle_done")
b0e53b15 2867 {
2868 // Send the information to ML
2869 TMonaLisaText mlStatus("SHUTTLE_status", "Done");
e7f62f16 2870
b0e53b15 2871 TList mlList;
2872 mlList.Add(&mlStatus);
2873
ee6f7523 2874 TString mlID;
2875 mlID.Form("%d", GetCurrentRun());
2876 fMonaLisa->SendParameters(&mlList, mlID);
b0e53b15 2877 }
2bb7b766 2878 } else {
2bb7b766 2879 TString statusStr(status);
2880 if(statusStr.Contains("done", TString::kIgnoreCase) ||
2881 statusStr.Contains("failed", TString::kIgnoreCase)){
eba76848 2882 setClause = Form("set %s=\"%s\"", detector, status);
2bb7b766 2883 } else {
2884 Log("SHUTTLE",
2885 Form("UpdateShuttleLogbook - Invalid status <%s> for detector %s",
2886 status, detector));
2887 return kFALSE;
2888 }
2889 }
57f50b3c 2890
2bb7b766 2891 TString whereClause = Form("where run=%d", GetCurrentRun());
2892
441b0e9c 2893 TString sqlQuery = Form("update %s %s %s",
2894 fConfig->GetShuttlelbTable(), setClause.Data(), whereClause.Data());
57f50b3c 2895
2bb7b766 2896 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2897
2898 // Query execution
2899 TSQLResult* aResult;
be48e3ea 2900 aResult = dynamic_cast<TSQLResult*> (fServer[3]->Query(sqlQuery));
2bb7b766 2901 if (!aResult) {
2902 Log("SHUTTLE", Form("UpdateShuttleLogbook - Can't execute query <%s>", sqlQuery.Data()));
2903 return kFALSE;
57f50b3c 2904 }
2bb7b766 2905 delete aResult;
57f50b3c 2906
2907 return kTRUE;
2908}
2909
2910//______________________________________________________________________________________________
2bb7b766 2911Int_t AliShuttle::GetCurrentRun() const
2912{
9827400b 2913 //
2914 // Get current run from logbook entry
2915 //
57f50b3c 2916
2bb7b766 2917 return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
57f50b3c 2918}
2919
2920//______________________________________________________________________________________________
2bb7b766 2921UInt_t AliShuttle::GetCurrentStartTime() const
2922{
9827400b 2923 //
2924 // get current start time
2925 //
57f50b3c 2926
2bb7b766 2927 return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
57f50b3c 2928}
2929
2930//______________________________________________________________________________________________
2bb7b766 2931UInt_t AliShuttle::GetCurrentEndTime() const
2932{
9827400b 2933 //
2934 // get current end time from logbook entry
2935 //
57f50b3c 2936
2bb7b766 2937 return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
57f50b3c 2938}
2939
675f64cd 2940//______________________________________________________________________________________________
2941UInt_t AliShuttle::GetCurrentYear() const
2942{
2943 //
2944 // Get current year from logbook entry
2945 //
2946
2947 if (!fLogbookEntry) return 0;
2948
2949 TTimeStamp startTime(GetCurrentStartTime());
2950 TString year = Form("%d",startTime.GetDate());
2951 year = year(0,4);
2952
2953 return year.Atoi();
2954}
2955
2956//______________________________________________________________________________________________
2957const char* AliShuttle::GetLHCPeriod() const
2958{
2959 //
2960 // Get current LHC period from logbook entry
2961 //
2962
2963 if (!fLogbookEntry) return 0;
2964
2965 return fLogbookEntry->GetRunParameter("LHCperiod");
2966}
2967
b948db8d 2968//______________________________________________________________________________________________
2969void AliShuttle::Log(const char* detector, const char* message)
2970{
9827400b 2971 //
2972 // Fill log string with a message
2973 //
b948db8d 2974
7d4cf768 2975 TString logRunDir = GetShuttleLogDir();
2976 if (GetCurrentRun() >=0)
2977 logRunDir += Form("/%d", GetCurrentRun());
2978
2979 void* dir = gSystem->OpenDirectory(logRunDir.Data());
84090f85 2980 if (dir == NULL) {
7d4cf768 2981 if (gSystem->mkdir(logRunDir.Data(), kTRUE)) {
36c99a6a 2982 AliError(Form("Can't open directory <%s>", GetShuttleLogDir()));
84090f85 2983 return;
2984 }
b948db8d 2985
84090f85 2986 } else {
2987 gSystem->FreeDirectory(dir);
2988 }
b948db8d 2989
cb343cfd 2990 TString toLog = Form("%s (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
e7f62f16 2991 if (GetCurrentRun() >= 0)
2992 toLog += Form("run %d - ", GetCurrentRun());
2bb7b766 2993 toLog += Form("%s", message);
2994
84090f85 2995 AliInfo(toLog.Data());
ffa29e93 2996
2997 // if we redirect the log output already to the file, leave here
2998 if (fOutputRedirected && strcmp(detector, "SHUTTLE") != 0)
2999 return;
b948db8d 3000
ffa29e93 3001 TString fileName = GetLogFileName(detector);
e7f62f16 3002
84090f85 3003 gSystem->ExpandPathName(fileName);
3004
3005 ofstream logFile;
3006 logFile.open(fileName, ofstream::out | ofstream::app);
3007
3008 if (!logFile.is_open()) {
3009 AliError(Form("Could not open file %s", fileName.Data()));
3010 return;
3011 }
7bfb2090 3012
84090f85 3013 logFile << toLog.Data() << "\n";
b948db8d 3014
84090f85 3015 logFile.close();
b948db8d 3016}
2bb7b766 3017
ffa29e93 3018//______________________________________________________________________________________________
3019TString AliShuttle::GetLogFileName(const char* detector) const
3020{
3021 //
3022 // returns the name of the log file for a given sub detector
3023 //
3024
3025 TString fileName;
3026
3027 if (GetCurrentRun() >= 0)
7d4cf768 3028 {
3029 fileName.Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(),
3030 detector, GetCurrentRun());
3031 } else {
ffa29e93 3032 fileName.Form("%s/%s.log", GetShuttleLogDir(), detector);
7d4cf768 3033 }
ffa29e93 3034
3035 return fileName;
3036}
3037
ee6f7523 3038//______________________________________________________________________________________________
3039void AliShuttle::SendAlive()
3040{
3041 // sends alive message to ML
3042
3043 TMonaLisaText mlStatus("SHUTTLE_status", "Alive");
3044
3045 TList mlList;
3046 mlList.Add(&mlStatus);
3047
3048 fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__");
3049}
3050
2bb7b766 3051//______________________________________________________________________________________________
3052Bool_t AliShuttle::Collect(Int_t run)
3053{
9827400b 3054 //
3055 // Collects conditions data for all UNPROCESSED run written to DAQ LogBook in case of run = -1 (default)
3056 // If a dedicated run is given this run is processed
3057 //
3058 // In operational mode, this is the Shuttle function triggered by the EOR signal.
3059 //
2bb7b766 3060
eba76848 3061 if (run == -1)
3062 Log("SHUTTLE","Collect - Shuttle called. Collecting conditions data for unprocessed runs");
3063 else
3064 Log("SHUTTLE", Form("Collect - Shuttle called. Collecting conditions data for run %d", run));
cb343cfd 3065
3066 SetLastAction("Starting");
2bb7b766 3067
ee6f7523 3068 // create ML instance
3069 if (!fMonaLisa)
3070 fMonaLisa = new TMonaLisaWriter(fConfig->GetMonitorHost(), fConfig->GetMonitorTable());
3071
ee6f7523 3072 SendAlive();
fbc112e3 3073 CountOpenRuns();
ee6f7523 3074
2bb7b766 3075 TString whereClause("where shuttle_done=0");
eba76848 3076 if (run != -1)
3077 whereClause += Form(" and run=%d", run);
2bb7b766 3078
3079 TObjArray shuttleLogbookEntries;
be48e3ea 3080 if (!QueryShuttleLogbook(whereClause, shuttleLogbookEntries))
3081 {
cb343cfd 3082 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
2bb7b766 3083 return kFALSE;
3084 }
3085
9e080f92 3086 if (shuttleLogbookEntries.GetEntries() == 0)
3087 {
3088 if (run == -1)
3089 Log("SHUTTLE","Collect - Found no UNPROCESSED runs in Shuttle logbook");
3090 else
3091 Log("SHUTTLE", Form("Collect - Run %d is already DONE "
3092 "or it does not exist in Shuttle logbook", run));
3093 return kTRUE;
3094 }
3095
be48e3ea 3096 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
3097 fFirstUnprocessed[iDet] = kTRUE;
3098
fc5a4708 3099 if (run != -1)
be48e3ea 3100 {
3101 // query Shuttle logbook for earlier runs, check if some detectors are unprocessed,
3102 // flag them into fFirstUnprocessed array
3103 TString whereClause(Form("where shuttle_done=0 and run < %d", run));
3104 TObjArray tmpLogbookEntries;
3105 if (!QueryShuttleLogbook(whereClause, tmpLogbookEntries))
3106 {
3107 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
3108 return kFALSE;
3109 }
3110
3111 TIter iter(&tmpLogbookEntries);
3112 AliShuttleLogbookEntry* anEntry = 0;
3113 while ((anEntry = dynamic_cast<AliShuttleLogbookEntry*> (iter.Next())))
3114 {
3115 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
3116 {
3117 if (anEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
3118 {
3119 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
3120 anEntry->GetRun(), GetDetName(iDet)));
3121 fFirstUnprocessed[iDet] = kFALSE;
3122 }
3123 }
3124
3125 }
3126
3127 }
3128
3129 if (!RetrieveConditionsData(shuttleLogbookEntries))
3130 {
cb343cfd 3131 Log("SHUTTLE", "Collect - Process of at least one run failed");
2bb7b766 3132 return kFALSE;
3133 }
3134
36c99a6a 3135 Log("SHUTTLE", "Collect - Requested run(s) successfully processed");
eba76848 3136 return kTRUE;
2bb7b766 3137}
3138
2bb7b766 3139//______________________________________________________________________________________________
3140Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
3141{
9827400b 3142 //
3143 // Retrieve conditions data for all runs that aren't processed yet
3144 //
2bb7b766 3145
3146 Bool_t hasError = kFALSE;
3147
3148 TIter iter(&dateEntries);
3149 AliShuttleLogbookEntry* anEntry;
3150
3151 while ((anEntry = (AliShuttleLogbookEntry*) iter.Next())){
3152 if (!Process(anEntry)){
3153 hasError = kTRUE;
3154 }
4b95672b 3155
3156 // clean SHUTTLE temp directory
d524ade6 3157 //TString filename = Form("%s/*.shuttle", GetShuttleTempDir());
3158 //RemoveFile(filename.Data());
2bb7b766 3159 }
3160
3161 return hasError == kFALSE;
3162}
cb343cfd 3163
3164//______________________________________________________________________________________________
3165ULong_t AliShuttle::GetTimeOfLastAction() const
3166{
9827400b 3167 //
3168 // Gets time of last action
3169 //
3170
cb343cfd 3171 ULong_t tmp;
36c99a6a 3172
cb343cfd 3173 fMonitoringMutex->Lock();
be48e3ea 3174
cb343cfd 3175 tmp = fLastActionTime;
36c99a6a 3176
cb343cfd 3177 fMonitoringMutex->UnLock();
36c99a6a 3178
cb343cfd 3179 return tmp;
3180}
3181
3182//______________________________________________________________________________________________
3183const TString AliShuttle::GetLastAction() const
3184{
9827400b 3185 //
cb343cfd 3186 // returns a string description of the last action
9827400b 3187 //
cb343cfd 3188
3189 TString tmp;
36c99a6a 3190
cb343cfd 3191 fMonitoringMutex->Lock();
3192
3193 tmp = fLastAction;
3194
3195 fMonitoringMutex->UnLock();
3196
36c99a6a 3197 return tmp;
cb343cfd 3198}
3199
3200//______________________________________________________________________________________________
3201void AliShuttle::SetLastAction(const char* action)
3202{
9827400b 3203 //
cb343cfd 3204 // updates the monitoring variables
9827400b 3205 //
36c99a6a 3206
cb343cfd 3207 fMonitoringMutex->Lock();
36c99a6a 3208
cb343cfd 3209 fLastAction = action;
3210 fLastActionTime = time(0);
3211
3212 fMonitoringMutex->UnLock();
3213}
eba76848 3214
3215//______________________________________________________________________________________________
3216const char* AliShuttle::GetRunParameter(const char* param)
3217{
9827400b 3218 //
3219 // returns run parameter read from DAQ logbook
3220 //
eba76848 3221
3222 if(!fLogbookEntry) {
3223 AliError("No logbook entry!");
3224 return 0;
3225 }
3226
3227 return fLogbookEntry->GetRunParameter(param);
3228}
57c1a579 3229
d386d623 3230//______________________________________________________________________________________________
9827400b 3231AliCDBEntry* AliShuttle::GetFromOCDB(const char* detector, const AliCDBPath& path)
d386d623 3232{
9827400b 3233 //
3234 // returns object from OCDB valid for current run
3235 //
d386d623 3236
9827400b 3237 if (fTestMode & kErrorOCDB)
3238 {
3239 Log(detector, "GetFromOCDB - In TESTMODE - Simulating error with OCDB");
3240 return 0;
3241 }
3242
d386d623 3243 AliCDBStorage *sto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
3244 if (!sto)
3245 {
9827400b 3246 Log(detector, "GetFromOCDB - Cannot activate main OCDB for query!");
d386d623 3247 return 0;
3248 }
3249
3250 return dynamic_cast<AliCDBEntry*> (sto->Get(path, GetCurrentRun()));
3251}
3252
57c1a579 3253//______________________________________________________________________________________________
3254Bool_t AliShuttle::SendMail()
3255{
9827400b 3256 //
3257 // sends a mail to the subdetector expert in case of preprocessor error
3258 //
3259
3260 if (fTestMode != kNone)
3261 return kTRUE;
57c1a579 3262
57c1a579 3263 TString to="";
3264 TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector));
3265 TObjString *anExpert=0;
3266 while ((anExpert = (TObjString*) iterExperts.Next()))
3267 {
3268 to += Form("%s,", anExpert->GetName());
3269 }
4508ab8b 3270 if (to.Length() > 0)
3271 to.Remove(to.Length()-1);
909732f7 3272 AliDebug(2, Form("to: %s",to.Data()));
57c1a579 3273
86aa42c3 3274 if (to.IsNull()) {
c88ad5db 3275 Log("SHUTTLE", "List of detector responsibles not yet set!");
36c99a6a 3276 return kFALSE;
3277 }
3278
fbc112e3 3279 void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
3280 if (dir == NULL)
3281 {
3282 if (gSystem->mkdir(GetShuttleLogDir(), kTRUE))
3283 {
3284 Log("SHUTTLE", Form("SendMail - Can't open directory <%s>", GetShuttleLogDir()));
3285 return kFALSE;
3286 }
3287
3288 } else {
3289 gSystem->FreeDirectory(dir);
3290 }
3291
4508ab8b 3292 TString bodyFileName;
3293 bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
3294 gSystem->ExpandPathName(bodyFileName);
3295
3296 ofstream mailBody;
3297 mailBody.open(bodyFileName, ofstream::out);
3298
3299 if (!mailBody.is_open())
3300 {
3301 Log("SHUTTLE", Form("Could not open mail body file %s", bodyFileName.Data()));
3302 return kFALSE;
3303 }
3304
57c1a579 3305 TString cc="alberto.colla@cern.ch";
3306
6a1146c4 3307 TString subject = Form("%s Shuttle preprocessor FAILED in run %d (run type = %s)!",
3308 fCurrentDetector.Data(), GetCurrentRun(), GetRunType());
909732f7 3309 AliDebug(2, Form("subject: %s", subject.Data()));
57c1a579 3310
3311 TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data());
3312 body += Form("SHUTTLE just detected that your preprocessor "
6a1146c4 3313 "failed processing run %d (run type = %s)!!\n\n",
3314 GetCurrentRun(), GetRunType());
7d4cf768 3315 body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n",
3316 fCurrentDetector.Data());
b0e53b15 3317 if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
3318 {
3319 body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
3320 } else {
4508ab8b 3321 body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD&time=168 \n\n");
b0e53b15 3322 }
3323
7d4cf768 3324
3325 TString logFolder = "logs";
3326 if (fConfig->GetRunMode() == AliShuttleConfig::kProd)
3327 logFolder += "_PROD";
3328
3329
546242fb 3330 body += Form("Find the %s log for the current run on \n\n"
7d4cf768 3331 "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n",
3332 fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(),
3333 fCurrentDetector.Data(), GetCurrentRun());
3334 body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data());
57c1a579 3335
909732f7 3336 AliDebug(2, Form("Body begin: %s", body.Data()));
57c1a579 3337
3338 mailBody << body.Data();
3339 mailBody.close();
3340 mailBody.open(bodyFileName, ofstream::out | ofstream::app);
3341
7d4cf768 3342 TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(),
3343 GetCurrentRun(), fCurrentDetector.Data(), GetCurrentRun());
57c1a579 3344 TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
3345 if (gSystem->Exec(tailCommand.Data()))
3346 {
3347 mailBody << Form("%s log file not found ...\n\n", fCurrentDetector.Data());
3348 }
3349
3350 TString endBody = Form("------------------------------------------------------\n\n");
675f64cd 3351 endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n");
3352 endBody += "Please do not answer this message directly, it is automatically generated.\n\n";
3353 endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n";
3354
3355 AliDebug(2, Form("Body end: %s", endBody.Data()));
3356
3357 mailBody << endBody.Data();
3358
3359 mailBody.close();
3360
3361 // send mail!
3362 TString mailCommand = Form("mail -s \"%s\" -c %s %s < %s",
3363 subject.Data(),
3364 cc.Data(),
3365 to.Data(),
3366 bodyFileName.Data());
3367 AliDebug(2, Form("mail command: %s", mailCommand.Data()));
3368
3369 Bool_t result = gSystem->Exec(mailCommand.Data());
3370
3371 return result == 0;
3372}
3373
3374//______________________________________________________________________________________________
3375Bool_t AliShuttle::SendMailToDCS()
3376{
3377 //
3378 // sends a mail to the DCS experts in case of DCS error
3379 //
3380
3381 if (fTestMode != kNone)
3382 return kTRUE;
3383
3384 void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
3385 if (dir == NULL)
3386 {
3387 if (gSystem->mkdir(GetShuttleLogDir(), kTRUE))
3388 {
3389 Log("SHUTTLE", Form("SendMailToDCS - Can't open directory <%s>", GetShuttleLogDir()));
3390 return kFALSE;
3391 }
3392
3393 } else {
3394 gSystem->FreeDirectory(dir);
3395 }
3396
3397 TString bodyFileName;
3398 bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
3399 gSystem->ExpandPathName(bodyFileName);
3400
3401 ofstream mailBody;
3402 mailBody.open(bodyFileName, ofstream::out);
3403
3404 if (!mailBody.is_open())
3405 {
3406 Log("SHUTTLE", Form("SendMailToDCS - Could not open mail body file %s", bodyFileName.Data()));
3407 return kFALSE;
3408 }
3409
3410 TString to="Vladimir.Fekete@cern.ch, Svetozar.Kapusta@cern.ch";
3411 //TString to="alberto.colla@cern.ch";
3412 AliDebug(2, Form("to: %s",to.Data()));
3413
3414 if (to.IsNull()) {
3415 Log("SHUTTLE", "List of detector responsibles not yet set!");
3416 return kFALSE;
3417 }
3418
3419 TString cc="alberto.colla@cern.ch";
3420
3421 TString subject = Form("Retrieval of data points for %s FAILED in run %d !",
3422 fCurrentDetector.Data(), GetCurrentRun());
3423 AliDebug(2, Form("subject: %s", subject.Data()));
3424
3425 TString body = Form("Dear DCS experts, \n\n");
3426 body += Form("SHUTTLE couldn\'t retrieve the data points for detector %s "
3427 "in run %d!!\n\n", fCurrentDetector.Data(), GetCurrentRun());
7d4cf768 3428 body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n",
3429 fCurrentDetector.Data());
b0e53b15 3430 if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
3431 {
3432 body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
3433 } else {
3434 body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD?time=168 \n\n");
3435 }
7d4cf768 3436
3437 TString logFolder = "logs";
3438 if (fConfig->GetRunMode() == AliShuttleConfig::kProd)
3439 logFolder += "_PROD";
3440
3441
675f64cd 3442 body += Form("Find the %s log for the current run on \n\n"
7d4cf768 3443 "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n",
3444 fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(),
3445 fCurrentDetector.Data(), GetCurrentRun());
3446 body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data());
675f64cd 3447
3448 AliDebug(2, Form("Body begin: %s", body.Data()));
3449
3450 mailBody << body.Data();
3451 mailBody.close();
3452 mailBody.open(bodyFileName, ofstream::out | ofstream::app);
3453
7d4cf768 3454 TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(),
3455 fCurrentDetector.Data(), GetCurrentRun());
675f64cd 3456 TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
3457 if (gSystem->Exec(tailCommand.Data()))
3458 {
3459 mailBody << Form("%s log file not found ...\n\n", fCurrentDetector.Data());
3460 }
3461
3462 TString endBody = Form("------------------------------------------------------\n\n");
36c99a6a 3463 endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n");
3464 endBody += "Please do not answer this message directly, it is automatically generated.\n\n";
546242fb 3465 endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n";
57c1a579 3466
909732f7 3467 AliDebug(2, Form("Body end: %s", endBody.Data()));
57c1a579 3468
3469 mailBody << endBody.Data();
3470
3471 mailBody.close();
3472
3473 // send mail!
3474 TString mailCommand = Form("mail -s \"%s\" -c %s %s < %s",
3475 subject.Data(),
3476 cc.Data(),
3477 to.Data(),
3478 bodyFileName.Data());
909732f7 3479 AliDebug(2, Form("mail command: %s", mailCommand.Data()));
57c1a579 3480
3481 Bool_t result = gSystem->Exec(mailCommand.Data());
3482
3483 return result == 0;
3484}
d386d623 3485
441b0e9c 3486//______________________________________________________________________________________________
9827400b 3487const char* AliShuttle::GetRunType()
441b0e9c 3488{
9827400b 3489 //
3490 // returns run type read from "run type" logbook
3491 //
441b0e9c 3492
3493 if(!fLogbookEntry) {
3494 AliError("No logbook entry!");
3495 return 0;
3496 }
3497
9827400b 3498 return fLogbookEntry->GetRunType();
441b0e9c 3499}
3500
4859271b 3501//______________________________________________________________________________________________
3502Bool_t AliShuttle::GetHLTStatus()
3503{
3504 // Return HLT status (ON=1 OFF=0)
3505 // Converts the HLT status from the status string read in the run logbook (not just a bool)
3506
3507 if(!fLogbookEntry) {
3508 AliError("No logbook entry!");
3509 return 0;
3510 }
3511
3512 // TODO implement when HLTStatus is inserted in run logbook
3513 //TString hltStatus = fLogbookEntry->GetRunParameter("HLTStatus");
3514 //if(hltStatus == "OFF") {return kFALSE};
3515
3516 return kTRUE;
3517}
3518
d386d623 3519//______________________________________________________________________________________________
3520void AliShuttle::SetShuttleTempDir(const char* tmpDir)
3521{
9827400b 3522 //
3523 // sets Shuttle temp directory
3524 //
d386d623 3525
3526 fgkShuttleTempDir = gSystem->ExpandPathName(tmpDir);
3527}
3528
3529//______________________________________________________________________________________________
3530void AliShuttle::SetShuttleLogDir(const char* logDir)
3531{
9827400b 3532 //
3533 // sets Shuttle log directory
3534 //
d386d623 3535
3536 fgkShuttleLogDir = gSystem->ExpandPathName(logDir);
3537}