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