Typo corrected.
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttleConfig.cxx
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$
18 Revision 1.19  2007/02/28 10:41:56  acolla
19 Run type field added in SHUTTLE framework. Run type is read from "run type" logbook and retrieved by
20 AliPreprocessor::GetRunType() function.
21 Added some ldap definition files.
22
23 Revision 1.18  2007/01/23 19:20:03  acolla
24 Removed old ldif files, added TOF, MCH ldif files. Added some options in
25 AliShuttleConfig::Print. Added in Ali Shuttle: SetShuttleTempDir and
26 SetShuttleLogDir
27
28 Revision 1.17  2007/01/18 11:17:47  jgrosseo
29 changing spaces to tabs ;-)
30
31 Revision 1.16  2007/01/18 11:10:35  jgrosseo
32 adding the possibility of defining DCS alias and data points with patterns
33 first pattern introduced: [N..M] to add all names between the two digits, this works also recursively.
34
35 Revision 1.15  2007/01/15 18:27:11  acolla
36 implementation of sending mail to subdetector expert in case the preprocessor fails.
37 shuttle.schema updated with expert's email entry
38
39 Revision 1.13  2006/12/07 08:51:26  jgrosseo
40 update (alberto):
41 table, db names in ldap configuration
42 added GRP preprocessor
43 DCS data can also be retrieved by data point
44
45 Revision 1.12  2006/11/16 16:16:48  jgrosseo
46 introducing strict run ordering flag
47 removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
48
49 Revision 1.11  2006/11/06 14:23:04  jgrosseo
50 major update (Alberto)
51 o) reading of run parameters from the logbook
52 o) online offline naming conversion
53 o) standalone DCSclient package
54
55 Revision 1.10  2006/10/20 15:22:59  jgrosseo
56 o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
57 o) Merging Collect, CollectAll, CollectNew function
58 o) Removing implementation of empty copy constructors (declaration still there!)
59
60 Revision 1.9  2006/10/02 16:38:39  jgrosseo
61 update (alberto):
62 fixed memory leaks
63 storing of objects that failed to be stored to the grid before
64 interfacing of shuttle status table in daq system
65
66 Revision 1.8  2006/08/15 10:50:00  jgrosseo
67 effc++ corrections (alberto)
68
69 Revision 1.7  2006/07/20 09:54:40  jgrosseo
70 introducing status management: The processing per subdetector is divided into several steps,
71 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
72 can keep track of the number of failures and skips further processing after a certain threshold is
73 exceeded. These thresholds can be configured in LDAP.
74
75 Revision 1.6  2006/07/19 10:09:55  jgrosseo
76 new configuration, accesst to DAQ FES (Alberto)
77
78 Revision 1.5  2006/07/10 13:01:41  jgrosseo
79 enhanced storing of last sucessfully processed run (alberto)
80
81 Revision 1.4  2006/06/12 09:11:16  jgrosseo
82 coding conventions (Alberto)
83
84 Revision 1.3  2006/06/06 14:26:40  jgrosseo
85 o) removed files that were moved to STEER
86 o) shuttle updated to follow the new interface (Alberto)
87
88 Revision 1.7  2006/05/12 09:07:16  colla
89 12/05/06
90 New configuration complete
91
92 Revision 1.2  2006/03/07 07:52:34  hristov
93 New version (B.Yordanov)
94
95 Revision 1.4  2005/11/19 14:20:31  byordano
96 logbook config added to AliShuttleConfig
97
98 Revision 1.3  2005/11/17 19:24:25  byordano
99 TList changed to TObjArray in AliShuttleConfig
100
101 Revision 1.2  2005/11/17 14:43:23  byordano
102 import to local CVS
103
104 Revision 1.1.1.1  2005/10/28 07:33:58  hristov
105 Initial import as subdirectory in AliRoot
106
107 Revision 1.1.1.1  2005/09/12 22:11:40  byordano
108 SHUTTLE package
109
110 Revision 1.3  2005/08/30 09:13:02  byordano
111 some docs added
112
113 */
114
115
116 //
117 // This class keeps the AliShuttle configuration.
118 // It reads the configuration for LDAP server.
119 // For every child entry in basedn which has schema type 'shuttleConfig'
120 // it creates a detector configuration. This configuration includes:
121 // DCS server host and port and the set of aliases for which data from
122 // will be retrieved (used by AliShuttle).
123 //
124
125
126 #include "AliShuttleConfig.h"
127 #include "AliShuttleInterface.h"
128
129 #include "AliLog.h"
130
131 #include <TSystem.h>
132 #include <TObjString.h>
133 #include <TLDAPResult.h>
134 #include <TLDAPEntry.h>
135 #include <TLDAPAttribute.h>
136
137
138 AliShuttleConfig::AliShuttleConfigHolder::AliShuttleConfigHolder(const TLDAPEntry* entry):
139 fDetector(""),
140 fDCSHost(""),
141 fDCSPort(0),
142 fDCSAliases(0),
143 fDCSDataPoints(0),
144 fDCSAliasesComp(0),
145 fDCSDataPointsComp(0),
146 fResponsibles(0),
147 fIsValid(kFALSE),
148 fSkipDCSQuery(kFALSE),
149 fStrictRunOrder(kFALSE)
150 {
151 // constructor of the shuttle configuration holder
152
153         TLDAPAttribute* anAttribute;
154         fDCSAliases = new TObjArray();
155         fDCSAliases->SetOwner(1);
156         fDCSDataPoints = new TObjArray();
157         fDCSDataPoints->SetOwner(1);
158         fDCSAliasesComp = new TObjArray();
159         fDCSAliasesComp->SetOwner(1);
160         fDCSDataPointsComp = new TObjArray();
161         fDCSDataPointsComp->SetOwner(1);
162         fResponsibles = new TObjArray();
163         fResponsibles->SetOwner(1);
164
165         anAttribute = entry->GetAttribute("det"); // MUST
166         if (!anAttribute)
167         {
168                 AliError(Form("Invalid configuration! No \"det\" attribute!"));
169                 return;
170         }
171         fDetector = anAttribute->GetValue();
172
173         anAttribute = entry->GetAttribute("StrictRunOrder"); // MAY
174         if (!anAttribute)
175         {
176                 AliWarning(Form("%s did not set StrictRunOrder flag - the default is FALSE",
177                                 fDetector.Data()));
178         } else {
179                 TString strictRunStr = anAttribute->GetValue();
180                 if (!(strictRunStr == "0" || strictRunStr == "1"))
181                 {
182                         AliError("Invalid configuration! StrictRunOrder flag must be 0 or 1!");
183                         return;
184                 }
185                 fStrictRunOrder = (Bool_t) strictRunStr.Atoi();
186         }
187
188         anAttribute = entry->GetAttribute("responsible"); // MUST
189         if (!anAttribute)
190         {
191                 AliError(Form("Invalid configuration! No \"responsible\" attribute!"));
192                 return;
193         }
194         const char* aResponsible;
195         while ((aResponsible = anAttribute->GetValue()))
196         {
197                 fResponsibles->AddLast(new TObjString(aResponsible));
198         }
199
200         anAttribute = entry->GetAttribute("DCSHost"); // MAY
201         if (!anAttribute)
202         {
203                 AliDebug(2,
204                         Form("%s has not DCS host entry - Shuttle will skip DCS data query!",
205                                 fDetector.Data()));
206                 fIsValid = kTRUE;
207                 fSkipDCSQuery = kTRUE;
208                 return;
209         }
210
211         fDCSHost = anAttribute->GetValue();
212
213         anAttribute = entry->GetAttribute("DCSPort"); // MAY
214         if (!anAttribute)
215         {
216                 AliError(Form("Invalid configuration! %s has DCS Host but no port number!",
217                                 fDetector.Data()));
218                 return;
219         }
220         TString portStr = anAttribute->GetValue();
221         fDCSPort = portStr.Atoi();
222
223         anAttribute = entry->GetAttribute("DCSalias"); // MAY
224         if (anAttribute)
225         {
226                 const char* anAlias;
227                 while ((anAlias = anAttribute->GetValue()))
228                 {
229                         fDCSAliasesComp->AddLast(new TObjString(anAlias));
230                         ExpandAndAdd(fDCSAliases, anAlias);
231                 }
232         }
233
234         anAttribute = entry->GetAttribute("DCSdatapoint"); // MAY
235         if (anAttribute)
236         {
237                 const char* aDataPoint;
238                 while ((aDataPoint = anAttribute->GetValue()))
239                 {
240                 fDCSDataPointsComp->AddLast(new TObjString(aDataPoint));
241                 ExpandAndAdd(fDCSDataPoints, aDataPoint);
242                 }
243         }
244
245         fIsValid = kTRUE;
246 }
247
248 //______________________________________________________________________________________________
249 void AliShuttleConfig::AliShuttleConfigHolder::ExpandAndAdd(TObjArray* target, const char* entry)
250 {
251         //
252         // adds <entry> to <target> applying expanding of the name
253         // [N..M] creates M-N+1 names with the corresponding digits
254         //
255
256         TString entryStr(entry);
257
258         Int_t begin = entryStr.Index("[");
259         Int_t end = entryStr.Index("]");
260         if (begin != -1 && end != -1 && end > begin)
261         {
262                 TString before(entryStr(0, begin));
263                 TString after(entryStr(end+1, entryStr.Length()));
264
265                 AliDebug(2, Form("Found [] pattern. Splitted input string %s %s", before.Data(), after.Data()));
266
267                 Int_t dotdot = entryStr.Index("..");
268
269                 TString nStr(entryStr(begin+1, dotdot-begin-1));
270                 TString mStr(entryStr(dotdot+2, end-dotdot-2));
271
272                 AliDebug(2, Form("Found [N..M] pattern. %s %s", nStr.Data(), mStr.Data()));
273
274                 if (nStr.IsDigit() && mStr.IsDigit())
275                 {
276                         Int_t n = nStr.Atoi();
277                         Int_t m = mStr.Atoi();
278
279                         Int_t nDigits = nStr.Length();
280                         TString formatStr;
281                         formatStr.Form("%%s%%0%dd%%s", nDigits);
282
283                         AliDebug(2, Form("Format string is %s", formatStr.Data()));
284
285                         for (Int_t current = n; current<=m; ++current)
286                         {
287                                 TString newEntry;
288                                 newEntry.Form(formatStr.Data(), before.Data(), current, after.Data());
289
290                                 AliDebug(2, Form("Calling recursive with %s", newEntry.Data()));
291
292                                 // and go recursive
293                                 ExpandAndAdd(target, newEntry);
294                         }
295
296                         // return here because we processed the entries already recursively.
297                         return;
298                 }
299         }
300
301         AliDebug(2, Form("Adding name %s", entry));
302         target->AddLast(new TObjString(entry));
303 }
304
305 //______________________________________________________________________________________________
306 AliShuttleConfig::AliShuttleConfigHolder::~AliShuttleConfigHolder()
307 {
308 // destructor of the shuttle configuration holder
309
310         delete fDCSAliases;
311         delete fDCSDataPoints;
312         delete fResponsibles;
313 }
314
315 ClassImp(AliShuttleConfig)
316
317 //______________________________________________________________________________________________
318 AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
319         const char* binddn, const char* password, const char* basedn):
320         fIsValid(kFALSE), fConfigHost(host),
321         fDAQlbHost(""), fDAQlbPort(), fDAQlbUser(""), fDAQlbPass(""),
322         fDAQlbDB(""), fDAQlbTable(""), fShuttlelbTable(""), fRunTypelbTable(""),
323         fMaxRetries(0), fPPTimeOut(0), fPPMaxMem(0), fDetectorMap(), fDetectorList(),
324         fShuttleInstanceHost(""), fProcessedDetectors(), fProcessAll(kFALSE)
325 {
326         //
327         // host: ldap server host
328         // port: ldap server port
329         // binddn: binddn used for ldap binding (simple bind is used!).
330         // password: password for binddn
331         // basedn: this is basedn whose childeren entries which have
332         // (objectClass=shuttleConfig) will be used as detector configurations.
333         //
334
335         fDetectorMap.SetOwner();
336         fDetectorList.SetOwner(0); //fDetectorList and fDetectorMap share the same object!
337         fProcessedDetectors.SetOwner();
338
339         TLDAPServer aServer(host, port, binddn, password, 3);
340
341         if (!aServer.IsConnected()) {
342                 AliError(Form("Can't connect to ldap server %s:%d",
343                                 host, port));
344                 return;
345         }
346
347         // reads configuration for the shuttle running on this machine
348
349         fShuttleInstanceHost = gSystem->HostName();
350         TString queryFilter = Form("(ShuttleHost=%s)", fShuttleInstanceHost.Data());
351
352         TLDAPResult* aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
353
354         if (!aResult) {
355                 AliError(Form("Can't find configuration with base DN: %s",
356                                 basedn));
357                 return;
358         }
359
360         if (aResult->GetCount() == 0) {
361                 AliError(Form("No Shuttle instance for host = %s!",
362                                         fShuttleInstanceHost.Data()));
363                 AliError(Form("All detectors will be processed."));
364                 fProcessAll=kTRUE;
365         }
366
367         if (aResult->GetCount() > 1) {
368                 AliError(Form("More than one Shuttle instance for host %s!",
369                                         fShuttleInstanceHost.Data()));
370                 delete aResult;
371                 return;
372         }
373
374         TLDAPEntry* anEntry = 0;
375         TLDAPAttribute* anAttribute = 0;
376
377         if(!fProcessAll){
378                 anEntry = aResult->GetNext();
379                 anAttribute = anEntry->GetAttribute("detectors");
380                 const char *detName;
381                 while((detName = anAttribute->GetValue())){
382                         TObjString *objDet= new TObjString(detName);
383                         fProcessedDetectors.Add(objDet);
384                 }
385         }
386
387         delete anEntry; delete aResult;
388
389         // Detector configuration (DCS Archive DB settings)
390
391         aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, "(objectClass=AliShuttleDetector)");
392         if (!aResult) {
393                 AliError(Form("Can't find configuration with base DN: %s", basedn));
394                 return;
395         }
396
397
398         while ((anEntry = aResult->GetNext())) {
399                 AliShuttleConfigHolder* aHolder = new AliShuttleConfigHolder(anEntry);
400                 delete anEntry;
401
402                 if (!aHolder->IsValid()) {
403                         AliError("Detector configuration error!");
404                         delete aHolder;
405                         delete aResult;
406                         return;
407                 }
408
409                 TObjString* detStr = new TObjString(aHolder->GetDetector());
410                 fDetectorMap.Add(detStr, aHolder);
411                 fDetectorList.AddLast(detStr);
412         }
413
414         delete aResult;
415
416         // Global configuration (DAQ logbook)
417
418         aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL,
419                         "(objectClass=AliShuttleGlobalConfig)");
420         if (!aResult) {
421                 AliError(Form("Can't find configuration with base DN: %s",
422                                 basedn));
423                 return;
424         }
425
426         if (aResult->GetCount() == 0) {
427                 AliError("Can't find DAQ logbook configuration!");
428                 delete aResult;
429                 return;
430         }
431
432         if (aResult->GetCount() > 1) {
433                 AliError("More than one DAQ logbook configuration found!");
434                 delete aResult;
435                 return;
436         }
437
438         anEntry = aResult->GetNext();
439
440         anAttribute = anEntry->GetAttribute("DAQLogbookHost");
441         if (!anAttribute) {
442                 AliError("Can't find DAQLogbookHost attribute!");
443                 delete anEntry; delete aResult;
444                 return;
445         }
446         fDAQlbHost = anAttribute->GetValue();
447
448         anAttribute = anEntry->GetAttribute("DAQLogbookPort"); // MAY
449         if (anAttribute)
450         {
451                 fDAQlbPort = ((TString) anAttribute->GetValue()).Atoi();
452         } else {
453                 fDAQlbPort = 3306; // mysql
454         }
455
456         anAttribute = anEntry->GetAttribute("DAQLogbookUser");
457         if (!anAttribute) {
458                 AliError("Can't find DAQLogbookUser attribute!");
459                 delete aResult; delete anEntry;
460                 return;
461         }
462         fDAQlbUser = anAttribute->GetValue();
463
464         anAttribute = anEntry->GetAttribute("DAQLogbookPassword");
465         if (!anAttribute) {
466                 AliError("Can't find DAQLogbookPassword attribute!");
467                 delete aResult; delete anEntry;
468                 return;
469         }
470         fDAQlbPass = anAttribute->GetValue();
471
472         anAttribute = anEntry->GetAttribute("DAQLogbookDB");
473         if (!anAttribute) {
474                 AliError("Can't find DAQLogbookDB attribute!");
475                 delete aResult; delete anEntry;
476                 return;
477         }
478         fDAQlbDB = anAttribute->GetValue();
479
480         anAttribute = anEntry->GetAttribute("DAQLogbookTable");
481         if (!anAttribute) {
482                 AliError("Can't find DAQLogbookTable attribute!");
483                 delete aResult; delete anEntry;
484                 return;
485         }
486         fDAQlbTable = anAttribute->GetValue();
487
488         anAttribute = anEntry->GetAttribute("ShuttleLogbookTable");
489         if (!anAttribute) {
490                 AliError("Can't find ShuttleLogbookTable attribute!");
491                 delete aResult; delete anEntry;
492                 return;
493         }
494         fShuttlelbTable = anAttribute->GetValue();
495
496         anAttribute = anEntry->GetAttribute("RunTypeLogbookTable");
497         if (!anAttribute) {
498                 AliError("Can't find RunTypeLogbookTable attribute!");
499                 delete aResult; delete anEntry;
500                 return;
501         }
502         fRunTypelbTable = anAttribute->GetValue();
503
504         anAttribute = anEntry->GetAttribute("MaxRetries");
505         if (!anAttribute) {
506                 AliError("Can't find MaxRetries attribute!");
507                 delete aResult; delete anEntry;
508                 return;
509         }
510         TString tmpStr = anAttribute->GetValue();
511         fMaxRetries = tmpStr.Atoi();
512
513         anAttribute = anEntry->GetAttribute("PPTimeOut");
514         if (!anAttribute) {
515                 AliError("Can't find PPTimeOut attribute!");
516                 delete aResult; delete anEntry;
517                 return;
518         }
519         tmpStr = anAttribute->GetValue();
520         fPPTimeOut = tmpStr.Atoi();
521
522         anAttribute = anEntry->GetAttribute("PPMaxMem");
523         if (!anAttribute) {
524                 AliError("Can't find PPMaxMem attribute!");
525                 delete aResult; delete anEntry;
526                 return;
527         }
528         tmpStr = anAttribute->GetValue();
529         fPPMaxMem = tmpStr.Atoi();
530         
531         delete aResult; delete anEntry;
532
533         // FXS configuration (FXS logbook and hosts)
534
535         for(int iSys=0;iSys<3;iSys++){
536                 queryFilter = Form("(system=%s)", AliShuttleInterface::GetSystemName(iSys));
537                 aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
538                 if (!aResult) {
539                         AliError(Form("Can't find configuration for system: %s",
540                                         AliShuttleInterface::GetSystemName(iSys)));
541                         return;
542                 }
543
544                 if (aResult->GetCount() != 1 ) {
545                         AliError("Error in FXS configuration!");
546                         delete aResult;
547                         return;
548                 }
549
550                 anEntry = aResult->GetNext();
551
552                 anAttribute = anEntry->GetAttribute("DBHost");
553                 if (!anAttribute) {
554                         AliError(Form ("Can't find DBHost attribute for %s!!",
555                                                 AliShuttleInterface::GetSystemName(iSys)));
556                         delete aResult; delete anEntry;
557                         return;
558                 }
559                 fFXSdbHost[iSys] = anAttribute->GetValue();
560
561                 anAttribute = anEntry->GetAttribute("DBPort"); // MAY
562                 if (anAttribute)
563                 {
564                         fFXSdbPort[iSys] = ((TString) anAttribute->GetValue()).Atoi();
565                 } else {
566                         fFXSdbPort[iSys] = 3306; // mysql
567                 }
568
569                 anAttribute = anEntry->GetAttribute("DBUser");
570                 if (!anAttribute) {
571                         AliError(Form ("Can't find DBUser attribute for %s!!",
572                                                 AliShuttleInterface::GetSystemName(iSys)));
573                         delete aResult; delete anEntry;
574                         return;
575                 }
576                 fFXSdbUser[iSys] = anAttribute->GetValue();
577
578                 anAttribute = anEntry->GetAttribute("DBPassword");
579                 if (!anAttribute) {
580                         AliError(Form ("Can't find DBPassword attribute for %s!!",
581                                                 AliShuttleInterface::GetSystemName(iSys)));
582                         delete aResult; delete anEntry;
583                         return;
584                 }
585                 fFXSdbPass[iSys] = anAttribute->GetValue();
586
587                 anAttribute = anEntry->GetAttribute("DBName");
588                 if (!anAttribute) {
589                         AliError(Form ("Can't find DBName attribute for %s!!",
590                                                 AliShuttleInterface::GetSystemName(iSys)));
591                         delete aResult; delete anEntry;
592                         return;
593                 }
594
595                 fFXSdbName[iSys] = anAttribute->GetValue();
596                 anAttribute = anEntry->GetAttribute("DBTable");
597                 if (!anAttribute) {
598                         AliError(Form ("Can't find DBTable attribute for %s!!",
599                                                 AliShuttleInterface::GetSystemName(iSys)));
600                         delete aResult; delete anEntry;
601                         return;
602                 }
603                 fFXSdbTable[iSys] = anAttribute->GetValue();
604
605                 anAttribute = anEntry->GetAttribute("FSHost");
606                 if (!anAttribute) {
607                         AliError(Form ("Can't find FSHost attribute for %s!!",
608                                                 AliShuttleInterface::GetSystemName(iSys)));
609                         delete aResult; delete anEntry;
610                         return;
611                 }
612                 fFXSHost[iSys] = anAttribute->GetValue();
613
614                 anAttribute = anEntry->GetAttribute("FSPort"); // MAY
615                 if (anAttribute)
616                 {
617                         fFXSPort[iSys] = ((TString) anAttribute->GetValue()).Atoi();
618                 } else {
619                         fFXSPort[iSys] = 22; // scp port number
620                 }
621
622                 anAttribute = anEntry->GetAttribute("FSUser");
623                 if (!anAttribute) {
624                         AliError(Form ("Can't find FSUser attribute for %s!!",
625                                                 AliShuttleInterface::GetSystemName(iSys)));
626                         delete aResult; delete anEntry;
627                         return;
628                 }
629                 fFXSUser[iSys] = anAttribute->GetValue();
630
631                 anAttribute = anEntry->GetAttribute("FSPassword");
632                 if (anAttribute) fFXSPass[iSys] = anAttribute->GetValue();
633
634                 delete aResult; delete anEntry;
635         }
636
637         fIsValid = kTRUE;
638 }
639
640 //______________________________________________________________________________________________
641 AliShuttleConfig::~AliShuttleConfig()
642 {
643 // destructor
644
645         fDetectorMap.DeleteAll();
646         fDetectorList.Clear();
647         fProcessedDetectors.Delete();
648 }
649
650 //______________________________________________________________________________________________
651 const TObjArray* AliShuttleConfig::GetDetectors() const
652 {
653         //
654         // returns collection of TObjString which contains the name
655         // of every detector which is in the configuration.
656         //
657
658         return &fDetectorList;
659 }
660
661 //______________________________________________________________________________________________
662 Bool_t AliShuttleConfig::HasDetector(const char* detector) const
663 {
664         //
665         // checks for paricular detector in the configuration.
666         //
667         return fDetectorMap.GetValue(detector) != NULL;
668 }
669
670 //______________________________________________________________________________________________
671 const char* AliShuttleConfig::GetDCSHost(const char* detector) const
672 {
673         //
674         // returns DCS server host used by particular detector
675         //
676         
677         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
678         if (!aHolder) {
679                 AliError(Form("There isn't configuration for detector: %s",
680                         detector));
681                 return NULL;
682         }
683
684         return aHolder->GetDCSHost();
685 }
686
687 //______________________________________________________________________________________________
688 Int_t AliShuttleConfig::GetDCSPort(const char* detector) const
689 {
690         //
691         // returns DCS server port used by particular detector
692         //
693
694
695         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
696         if (!aHolder) {
697                 AliError(Form("There isn't configuration for detector: %s",
698                         detector));
699                 return 0;
700         }
701
702         return aHolder->GetDCSPort();
703 }
704
705 //______________________________________________________________________________________________
706 const TObjArray* AliShuttleConfig::GetDCSAliases(const char* detector) const
707 {
708         //
709         // returns collection of TObjString which represents the set of aliases
710         // which used for data retrieval for particular detector
711         //
712
713         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
714         if (!aHolder) {
715                 AliError(Form("There isn't configuration for detector: %s",
716                         detector));
717                 return NULL;
718         }
719
720         return aHolder->GetDCSAliases();
721 }
722
723 //______________________________________________________________________________________________
724 const TObjArray* AliShuttleConfig::GetDCSDataPoints(const char* detector) const
725 {
726         //
727         // returns collection of TObjString which represents the set of aliases
728         // which used for data retrieval for particular detector
729         //
730
731         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
732         if (!aHolder) {
733                 AliError(Form("There isn't configuration for detector: %s",
734                         detector));
735                 return NULL;
736         }
737
738         return aHolder->GetDCSDataPoints();
739 }
740
741 //______________________________________________________________________________________________
742 const TObjArray* AliShuttleConfig::GetResponsibles(const char* detector) const
743 {
744         //
745         // returns collection of TObjString which represents the list of mail addresses
746         // of the detector's responsible(s)
747         //
748
749         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
750         if (!aHolder) {
751                 AliError(Form("There isn't configuration for detector: %s",
752                         detector));
753                 return NULL;
754         }
755
756         return aHolder->GetResponsibles();
757 }
758
759 //______________________________________________________________________________________________
760 Bool_t AliShuttleConfig::HostProcessDetector(const char* detector) const
761 {
762         // return TRUE if detector is handled by host or if fProcessAll is TRUE
763
764         if(fProcessAll) return kTRUE;
765         TIter iter(&fProcessedDetectors);
766         TObjString* detName;
767         while((detName = (TObjString*) iter.Next())){
768                 if(detName->String() == detector) return kTRUE;
769         }
770         return kFALSE;
771 }
772
773 //______________________________________________________________________________________________
774 Bool_t AliShuttleConfig::StrictRunOrder(const char* detector) const
775 {
776         // return TRUE if detector wants strict run ordering of stored data
777
778         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
779         if (!aHolder)
780         {
781                 AliError(Form("There isn't configuration for detector: %s",
782                         detector));
783                 return kTRUE;
784         }
785
786         return aHolder->StrictRunOrder();
787 }
788
789 //______________________________________________________________________________________________
790 void AliShuttleConfig::Print(Option_t* option) const
791 {
792 // print configuration
793 // options : "": print configuration for all detectors, aliases and DPs in compacted format
794 //           "uncompact": print configuration for all detectors, aliases and DPs in uncompacted format
795 //           "DET": print configuration for DET, aliases and DPs in compacted format
796 //           "DET, uncompact": print configuration for DET, aliases and DPs in uncompacted format
797
798         TString result;
799         result += '\n';
800
801         result += "####################################################\n";
802         result += Form(" Shuttle configuration from %s \n", fConfigHost.Data());
803         result += "####################################################\n";
804         result += Form("\nShuttle running on %s \n", fShuttleInstanceHost.Data());
805
806         if(fProcessAll) {
807                 result += Form("All detectors will be processed! \n");
808         } else {
809                 result += "Detectors processed by this host: ";
810                 TIter it(&fProcessedDetectors);
811                 TObjString* aDet;
812                 while ((aDet = (TObjString*) it.Next())) {
813                         result += Form("%s ", aDet->String().Data());
814                 }
815                 result += "\n";
816         }
817
818         result += Form("PP time out = %d - Max PP memsize = %d KB - Max total retries = %d\n\n", fPPTimeOut, fPPMaxMem, fMaxRetries);
819         result += "------------------------------------------------------\n";
820
821         result += Form("Logbook Configuration \n\n \tHost: %s:%d; \tUser: %s; ",
822                 fDAQlbHost.Data(), fDAQlbPort, fDAQlbUser.Data());
823
824 //      result += "Password: ";
825 //      result.Append('*', fDAQlbPass.Length());
826         result += Form("\tDB: %s; \tTables: %s, %s, %s",
827                 fDAQlbDB.Data(), fDAQlbTable.Data(), fShuttlelbTable.Data(), fRunTypelbTable.Data());
828
829         result += "\n\n";
830
831         result += "------------------------------------------------------\n";
832         result += "FXS configuration\n\n";
833
834         for(int iSys=0;iSys<3;iSys++){
835                 result += Form("*** %s ***\n", AliShuttleInterface::GetSystemName(iSys));
836                 result += Form("\tDB  host: %s:%d; \tUser: %s; \tName: %s; \tTable: %s\n",
837                                                 fFXSdbHost[iSys].Data(), fFXSdbPort[iSys], fFXSdbUser[iSys].Data(),
838                                                 fFXSdbName[iSys].Data(), fFXSdbTable[iSys].Data());
839                 // result += Form("DB Password:",fFXSdbPass[iSys].Data());
840                 result += Form("\tFXS host: %s:%d; \tUser: %s\n\n", fFXSHost[iSys].Data(), fFXSPort[iSys],
841                                                 fFXSUser[iSys].Data());
842                 // result += Form("FXS Password:",fFXSPass[iSys].Data());
843         }
844
845         TString optStr(option);
846
847         result += "------------------------------------------------------\n";
848         result += "Detector-specific configuration\n\n";
849         TIter iter(fDetectorMap.GetTable());
850         TPair* aPair;
851         while ((aPair = (TPair*) iter.Next())) {
852                 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) aPair->Value();
853                 if (option != 0 && !optStr.Contains(aHolder->GetDetector()) && optStr.CompareTo("uncompact",TString::kIgnoreCase) != 0 )
854                                 continue;
855                 result += Form("*** %s *** \n", aHolder->GetDetector());
856
857                 const TObjArray* responsibles = aHolder->GetResponsibles();
858                 if (responsibles->GetEntries() != 0)
859                 {
860                         result += "\tDetector responsible(s): ";
861                         TIter it(responsibles);
862                         TObjString* aResponsible;
863                         while ((aResponsible = (TObjString*) it.Next()))
864                         {
865                                 result += Form("%s ", aResponsible->String().Data());
866                         }
867                         result += "\n";
868                 }
869
870                 result += Form("\tStrict run ordering: %s \n", aHolder->StrictRunOrder() ? "YES" : "NO");
871                 if(aHolder->SkipDCSQuery())
872                 {
873                         result += "\n";
874                         continue;
875                 }
876                 result += Form("\tAmanda server: %s:%d \n", aHolder->GetDCSHost(), aHolder->GetDCSPort());
877
878                 const TObjArray* aliases = 0;
879                 if (optStr.Contains("uncompact",TString::kIgnoreCase))
880                 {
881                         aliases = aHolder->GetDCSAliases();
882                 } else {
883                         aliases = aHolder->GetCompactDCSAliases();
884                 }
885
886                 if (aliases->GetEntries() != 0)
887                 {
888                         result += "\tDCS Aliases: ";
889                         TIter it(aliases);
890                         TObjString* anAlias;
891                         while ((anAlias = (TObjString*) it.Next()))
892                         {
893                                 result += Form("%s ", anAlias->String().Data());
894                         }
895                         result += "\n";
896                 }
897
898                 const TObjArray* dataPoints = 0;
899                 if (optStr.Contains("uncompact",TString::kIgnoreCase))
900                 {
901                         dataPoints = aHolder->GetDCSDataPoints();
902                 } else {
903                         dataPoints = aHolder->GetCompactDCSDataPoints();
904                 }
905                 if (dataPoints->GetEntries() != 0)
906                 {
907                         result += "\tDCS Data Points: ";
908                         TIter it(dataPoints);
909                         TObjString* aDataPoint;
910                         while ((aDataPoint = (TObjString*) it.Next())) {
911                                 result += Form("%s ", aDataPoint->String().Data());
912                         }
913                                 result += "\n";
914                 }
915                 result += "\n";
916         }
917
918         if(!fIsValid) result += "\n\n********** !!!!! Configuration is INVALID !!!!! **********\n";
919
920         AliInfo(result);
921 }