update (alberto):
[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.12  2006/11/16 16:16:48  jgrosseo
19 introducing strict run ordering flag
20 removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
21
22 Revision 1.11  2006/11/06 14:23:04  jgrosseo
23 major update (Alberto)
24 o) reading of run parameters from the logbook
25 o) online offline naming conversion
26 o) standalone DCSclient package
27
28 Revision 1.10  2006/10/20 15:22:59  jgrosseo
29 o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
30 o) Merging Collect, CollectAll, CollectNew function
31 o) Removing implementation of empty copy constructors (declaration still there!)
32
33 Revision 1.9  2006/10/02 16:38:39  jgrosseo
34 update (alberto):
35 fixed memory leaks
36 storing of objects that failed to be stored to the grid before
37 interfacing of shuttle status table in daq system
38
39 Revision 1.8  2006/08/15 10:50:00  jgrosseo
40 effc++ corrections (alberto)
41
42 Revision 1.7  2006/07/20 09:54:40  jgrosseo
43 introducing status management: The processing per subdetector is divided into several steps,
44 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
45 can keep track of the number of failures and skips further processing after a certain threshold is
46 exceeded. These thresholds can be configured in LDAP.
47
48 Revision 1.6  2006/07/19 10:09:55  jgrosseo
49 new configuration, accesst to DAQ FES (Alberto)
50
51 Revision 1.5  2006/07/10 13:01:41  jgrosseo
52 enhanced storing of last sucessfully processed run (alberto)
53
54 Revision 1.4  2006/06/12 09:11:16  jgrosseo
55 coding conventions (Alberto)
56
57 Revision 1.3  2006/06/06 14:26:40  jgrosseo
58 o) removed files that were moved to STEER
59 o) shuttle updated to follow the new interface (Alberto)
60
61 Revision 1.7  2006/05/12 09:07:16  colla
62 12/05/06
63 New configuration complete
64
65 Revision 1.2  2006/03/07 07:52:34  hristov
66 New version (B.Yordanov)
67
68 Revision 1.4  2005/11/19 14:20:31  byordano
69 logbook config added to AliShuttleConfig
70
71 Revision 1.3  2005/11/17 19:24:25  byordano
72 TList changed to TObjArray in AliShuttleConfig
73
74 Revision 1.2  2005/11/17 14:43:23  byordano
75 import to local CVS
76
77 Revision 1.1.1.1  2005/10/28 07:33:58  hristov
78 Initial import as subdirectory in AliRoot
79
80 Revision 1.1.1.1  2005/09/12 22:11:40  byordano
81 SHUTTLE package
82
83 Revision 1.3  2005/08/30 09:13:02  byordano
84 some docs added
85
86 */
87
88
89 //
90 // This class keeps the AliShuttle configuration.
91 // It reads the configuration for LDAP server.
92 // For every child entry in basedn which has schema type 'shuttleConfig'
93 // it creates a detector configuration. This configuration includes:
94 // DCS server host and port and the set of aliases for which data from
95 // will be retrieved (used by AliShuttle).
96 //
97
98
99 #include "AliShuttleConfig.h"
100 #include "AliShuttleInterface.h"
101
102 #include "AliLog.h"
103
104 #include <TSystem.h>
105 #include <TObjString.h>
106 #include <TLDAPResult.h>
107 #include <TLDAPEntry.h>
108 #include <TLDAPAttribute.h>
109
110
111 AliShuttleConfig::AliShuttleConfigHolder::AliShuttleConfigHolder(const TLDAPEntry* entry):
112 fDetector(""),
113 fDCSHost(""),
114 fDCSPort(0),
115 fIsValid(kFALSE),
116 fSkipDCSQuery(kFALSE),
117 fStrictRunOrder(kFALSE)
118 {
119 // constructor of the shuttle configuration holder
120
121         TLDAPAttribute* anAttribute;
122         fDCSAliases = new TObjArray();
123         fDCSAliases->SetOwner(1);
124         fDCSDataPoints = new TObjArray();
125         fDCSDataPoints->SetOwner(1);
126
127         anAttribute = entry->GetAttribute("det"); // MUST
128         if (!anAttribute)
129         {
130                 AliError(Form("Invalid configuration! No \"det\" attribute!"));
131                 return;
132         }
133         fDetector = anAttribute->GetValue();
134
135         anAttribute = entry->GetAttribute("StrictRunOrder"); // MAY
136         if (!anAttribute)
137         {
138                 AliWarning(Form("%s did not set StrictRunOrder flag - the default is FALSE",
139                                 fDetector.Data()));
140         } else {
141                 TString strictRunStr = anAttribute->GetValue();
142                 if (!(strictRunStr == "0" || strictRunStr == "1"))
143                 {
144                         AliError("Invalid configuration! StrictRunOrder flag must be 0 or 1!");
145                         return;
146                 }
147                 fStrictRunOrder = (Bool_t) strictRunStr.Atoi();
148         }
149
150         anAttribute = entry->GetAttribute("DCSHost"); // MAY
151         if (!anAttribute)
152         {
153                 AliWarning(
154                         Form("%s has not DCS host entry - Shuttle will skip DCS data query!",
155                                 fDetector.Data()));
156                 fIsValid = kTRUE;
157                 fSkipDCSQuery = kTRUE;
158                 return;
159         }
160
161         fDCSHost = anAttribute->GetValue();
162
163         anAttribute = entry->GetAttribute("DCSPort"); // MAY
164         if (!anAttribute)
165         {
166                 AliError(Form("Invalid configuration! %s has DCS Host but no port number!",
167                                 fDetector.Data()));
168                 return;
169         }
170         TString portStr = anAttribute->GetValue();
171         fDCSPort = portStr.Atoi();
172
173         anAttribute = entry->GetAttribute("DCSalias"); // MAY
174         if (anAttribute)
175         {
176                 const char* anAlias;
177                 while ((anAlias = anAttribute->GetValue()))
178                 {
179                         fDCSAliases->AddLast(new TObjString(anAlias));
180                 }
181         }
182
183         anAttribute = entry->GetAttribute("DCSdatapoint"); // MAY
184         if (anAttribute)
185         {
186                 const char* aDataPoint;
187                 while ((aDataPoint = anAttribute->GetValue()))
188                 {
189                         fDCSDataPoints->AddLast(new TObjString(aDataPoint));
190                 }
191         }
192
193         fIsValid = kTRUE;
194
195
196 }
197
198 //______________________________________________________________________________________________
199 AliShuttleConfig::AliShuttleConfigHolder::~AliShuttleConfigHolder()
200 {
201 // destructor of the shuttle configuration holder
202
203         delete fDCSAliases;
204         delete fDCSDataPoints;
205 }
206
207 ClassImp(AliShuttleConfig)
208
209 //______________________________________________________________________________________________
210 AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
211         const char* binddn, const char* password, const char* basedn):
212         fIsValid(kFALSE),
213         fDAQlbHost(""), fDAQlbUser(""), fDAQlbPass(""),
214         fMaxRetries(0), fPPTimeOut(0), fDetectorMap(), fDetectorList(),
215         fShuttleInstanceHost(""), fProcessedDetectors(), fProcessAll(kFALSE)
216 {
217         //
218         // host: ldap server host
219         // port: ldap server port
220         // binddn: binddn used for ldap binding (simple bind is used!).
221         // password: password for binddn
222         // basedn: this is basedn whose childeren entries which have
223         // (objectClass=shuttleConfig) will be used as detector configurations.
224         //
225
226         fDetectorMap.SetOwner();
227         fDetectorList.SetOwner(0); //fDetectorList and fDetectorMap share the same object!
228         fProcessedDetectors.SetOwner();
229
230         TLDAPServer aServer(host, port, binddn, password, 3);
231
232         if (!aServer.IsConnected()) {
233                 AliError(Form("Can't connect to ldap server %s:%d",
234                                 host, port));
235                 return;
236         }
237
238         // reads configuration for the shuttle running on this machine
239
240         fShuttleInstanceHost = gSystem->HostName();
241         TString queryFilter = Form("(ShuttleHost=%s)", fShuttleInstanceHost.Data());
242
243         TLDAPResult* aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
244
245         if (!aResult) {
246                 AliError(Form("Can't find configuration with base DN: %s",
247                                 basedn));
248                 return;
249         }
250
251         if (aResult->GetCount() == 0) {
252                 AliError(Form("No Shuttle instance for host = %s!",
253                                         fShuttleInstanceHost.Data()));
254                 AliError(Form("All detectors will be processed."));
255                 fProcessAll=kTRUE;
256         }
257
258         if (aResult->GetCount() > 1) {
259                 AliError(Form("More than one Shuttle instance for host %s!",
260                                         fShuttleInstanceHost.Data()));
261                 delete aResult;
262                 return;
263         }
264
265         TLDAPEntry* anEntry = 0;
266         TLDAPAttribute* anAttribute = 0;
267
268         if(!fProcessAll){
269                 anEntry = aResult->GetNext();
270                 anAttribute = anEntry->GetAttribute("detectors");
271                 const char *detName;
272                 while((detName = anAttribute->GetValue())){
273                         TObjString *objDet= new TObjString(detName);
274                         fProcessedDetectors.Add(objDet);
275                 }
276         }
277
278         delete anEntry; delete aResult;
279
280         // Detector configuration (DCS Archive DB settings)
281
282         aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, "(objectClass=AliShuttleDetector)");
283         if (!aResult) {
284                 AliError(Form("Can't find configuration with base DN: %s", basedn));
285                 return;
286         }
287
288
289         while ((anEntry = aResult->GetNext())) {
290                 AliShuttleConfigHolder* aHolder = new AliShuttleConfigHolder(anEntry);
291                 delete anEntry;
292
293                 if (!aHolder->IsValid()) {
294                         AliError("Detector configuration error!");
295                         delete aHolder;
296                         delete aResult;
297                         return;
298                 }
299
300                 TObjString* detStr = new TObjString(aHolder->GetDetector());
301                 fDetectorMap.Add(detStr, aHolder);
302                 fDetectorList.AddLast(detStr);
303         }
304
305         delete aResult;
306
307         // Global configuration (DAQ logbook)
308
309         aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL,
310                         "(objectClass=AliShuttleGlobalConfig)");
311         if (!aResult) {
312                 AliError(Form("Can't find configuration with base DN: %s",
313                                 basedn));
314                 return;
315         }
316
317         if (aResult->GetCount() == 0) {
318                 AliError("Can't find DAQ logbook configuration!");
319                 delete aResult;
320                 return;
321         }
322
323         if (aResult->GetCount() > 1) {
324                 AliError("More than one DAQ logbook configuration found!");
325                 delete aResult;
326                 return;
327         }
328
329         anEntry = aResult->GetNext();
330
331         anAttribute = anEntry->GetAttribute("DAQLogbookHost");
332         if (!anAttribute) {
333                 AliError("Can't find DAQLogbookHost attribute!");
334                 delete anEntry; delete aResult;
335                 return;
336         }
337         fDAQlbHost = anAttribute->GetValue();
338
339         anAttribute = anEntry->GetAttribute("DAQLogbookUser");
340         if (!anAttribute) {
341                 AliError("Can't find DAQLogbookUser attribute!");
342                 delete aResult; delete anEntry;
343                 return;
344         }
345         fDAQlbUser = anAttribute->GetValue();
346
347         anAttribute = anEntry->GetAttribute("DAQLogbookPassword");
348         if (!anAttribute) {
349                 AliError("Can't find DAQLogbookPassword attribute!");
350                 delete aResult; delete anEntry;
351                 return;
352         }
353         fDAQlbPass = anAttribute->GetValue();
354
355         anAttribute = anEntry->GetAttribute("DAQLogbookDB");
356         if (!anAttribute) {
357                 AliError("Can't find DAQLogbookDB attribute!");
358                 delete aResult; delete anEntry;
359                 return;
360         }
361         fDAQlbDB = anAttribute->GetValue();
362
363         anAttribute = anEntry->GetAttribute("DAQLogbookTable");
364         if (!anAttribute) {
365                 AliError("Can't find DAQLogbookTable attribute!");
366                 delete aResult; delete anEntry;
367                 return;
368         }
369         fDAQlbTable = anAttribute->GetValue();
370
371
372         anAttribute = anEntry->GetAttribute("MaxRetries");
373         if (!anAttribute) {
374                 AliError("Can't find MaxRetries attribute!");
375                 delete aResult; delete anEntry;
376                 return;
377         }
378         TString tmpStr = anAttribute->GetValue();
379         fMaxRetries = tmpStr.Atoi();
380
381         anAttribute = anEntry->GetAttribute("PPTimeOut");
382         if (!anAttribute) {
383                 AliError("Can't find PPTimeOut attribute!");
384                 delete aResult; delete anEntry;
385                 return;
386         }
387         tmpStr = anAttribute->GetValue();
388         fPPTimeOut = tmpStr.Atoi();
389
390         delete aResult; delete anEntry;
391
392         // FXS configuration (FXS logbook and hosts)
393
394         for(int iSys=0;iSys<3;iSys++){
395                 queryFilter = Form("(system=%s)", AliShuttleInterface::GetSystemName(iSys));
396                 aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
397                 if (!aResult) {
398                         AliError(Form("Can't find configuration for system: %s",
399                                         AliShuttleInterface::GetSystemName(iSys)));
400                         return;
401                 }
402
403                 if (aResult->GetCount() != 1 ) {
404                         AliError("Error in FXS configuration!");
405                         delete aResult;
406                         return;
407                 }
408
409                 anEntry = aResult->GetNext();
410
411                 anAttribute = anEntry->GetAttribute("DBHost");
412                 if (!anAttribute) {
413                         AliError(Form ("Can't find LogbookHost attribute for %s!!",
414                                                 AliShuttleInterface::GetSystemName(iSys)));
415                         delete aResult; delete anEntry;
416                         return;
417                 }
418                 fFXSdbHost[iSys] = anAttribute->GetValue();
419
420                 anAttribute = anEntry->GetAttribute("DBUser");
421                 if (!anAttribute) {
422                         AliError(Form ("Can't find DBUser attribute for %s!!",
423                                                 AliShuttleInterface::GetSystemName(iSys)));
424                         delete aResult; delete anEntry;
425                         return;
426                 }
427                 fFXSdbUser[iSys] = anAttribute->GetValue();
428
429                 anAttribute = anEntry->GetAttribute("DBPassword");
430                 if (!anAttribute) {
431                         AliError(Form ("Can't find DBPassword attribute for %s!!",
432                                                 AliShuttleInterface::GetSystemName(iSys)));
433                         delete aResult; delete anEntry;
434                         return;
435                 }
436                 fFXSdbPass[iSys] = anAttribute->GetValue();
437
438                 anAttribute = anEntry->GetAttribute("DBName");
439                 if (!anAttribute) {
440                         AliError(Form ("Can't find DBName attribute for %s!!",
441                                                 AliShuttleInterface::GetSystemName(iSys)));
442                         delete aResult; delete anEntry;
443                         return;
444                 }
445
446                 fFXSdbName[iSys] = anAttribute->GetValue();
447                 anAttribute = anEntry->GetAttribute("DBTable");
448                 if (!anAttribute) {
449                         AliError(Form ("Can't find DBTable attribute for %s!!",
450                                                 AliShuttleInterface::GetSystemName(iSys)));
451                         delete aResult; delete anEntry;
452                         return;
453                 }
454                 fFXSdbTable[iSys] = anAttribute->GetValue();
455
456                 anAttribute = anEntry->GetAttribute("FSHost");
457                 if (!anAttribute) {
458                         AliError(Form ("Can't find FSHost attribute for %s!!",
459                                                 AliShuttleInterface::GetSystemName(iSys)));
460                         delete aResult; delete anEntry;
461                         return;
462                 }
463                 fFXSHost[iSys] = anAttribute->GetValue();
464
465                 anAttribute = anEntry->GetAttribute("FSUser");
466                 if (!anAttribute) {
467                         AliError(Form ("Can't find FSUser attribute for %s!!",
468                                                 AliShuttleInterface::GetSystemName(iSys)));
469                         delete aResult; delete anEntry;
470                         return;
471                 }
472                 fFXSUser[iSys] = anAttribute->GetValue();
473
474                 anAttribute = anEntry->GetAttribute("FSPassword");
475                 if (anAttribute) fFXSPass[iSys] = anAttribute->GetValue();
476
477                 delete aResult; delete anEntry;
478         }
479
480         fIsValid = kTRUE;
481 }
482
483 //______________________________________________________________________________________________
484 AliShuttleConfig::~AliShuttleConfig()
485 {
486 // destructor
487
488         fDetectorMap.DeleteAll();
489         fDetectorList.Clear();
490         fProcessedDetectors.Delete();
491 }
492
493 //______________________________________________________________________________________________
494 const TObjArray* AliShuttleConfig::GetDetectors() const
495 {
496         //
497         // returns collection of TObjString which contains the name
498         // of every detector which is in the configuration.
499         //
500
501         return &fDetectorList;
502 }
503
504 //______________________________________________________________________________________________
505 Bool_t AliShuttleConfig::HasDetector(const char* detector) const
506 {
507         //
508         // checks for paricular detector in the configuration.
509         //
510         return fDetectorMap.GetValue(detector) != NULL;
511 }
512
513 //______________________________________________________________________________________________
514 const char* AliShuttleConfig::GetDCSHost(const char* detector) const
515 {
516         //
517         // returns DCS server host used by particular detector
518         //
519         
520         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
521         if (!aHolder) {
522                 AliError(Form("There isn't configuration for detector: %s",
523                         detector));
524                 return NULL;
525         }
526
527         return aHolder->GetDCSHost();
528 }
529
530 //______________________________________________________________________________________________
531 Int_t AliShuttleConfig::GetDCSPort(const char* detector) const
532 {
533         //
534         // returns DCS server port used by particular detector
535         //
536
537
538         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
539         if (!aHolder) {
540                 AliError(Form("There isn't configuration for detector: %s",
541                         detector));
542                 return 0;
543         }
544
545         return aHolder->GetDCSPort();
546 }
547
548 //______________________________________________________________________________________________
549 const TObjArray* AliShuttleConfig::GetDCSAliases(const char* detector) const
550 {
551         //
552         // returns collection of TObjString which represents the set of aliases
553         // which used for data retrieval for particular detector
554         //
555
556         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
557         if (!aHolder) {
558                 AliError(Form("There isn't configuration for detector: %s",
559                         detector));
560                 return NULL;
561         }
562
563         return aHolder->GetDCSAliases();
564 }
565
566 //______________________________________________________________________________________________
567 const TObjArray* AliShuttleConfig::GetDCSDataPoints(const char* detector) const
568 {
569         //
570         // returns collection of TObjString which represents the set of aliases
571         // which used for data retrieval for particular detector
572         //
573
574         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
575         if (!aHolder) {
576                 AliError(Form("There isn't configuration for detector: %s",
577                         detector));
578                 return NULL;
579         }
580
581         return aHolder->GetDCSDataPoints();
582 }
583
584 //______________________________________________________________________________________________
585 Bool_t AliShuttleConfig::HostProcessDetector(const char* detector) const
586 {
587         // return TRUE if detector is handled by host or if fProcessAll is TRUE
588
589         if(fProcessAll) return kTRUE;
590         TIter iter(&fProcessedDetectors);
591         TObjString* detName;
592         while((detName = (TObjString*) iter.Next())){
593                 if(detName->String() == detector) return kTRUE;
594         }
595         return kFALSE;
596 }
597
598 //______________________________________________________________________________________________
599 Bool_t AliShuttleConfig::StrictRunOrder(const char* detector) const
600 {
601         // return TRUE if detector wants strict run ordering of stored data
602
603         AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
604         if (!aHolder)
605         {
606                 AliError(Form("There isn't configuration for detector: %s",
607                         detector));
608                 return kTRUE;
609         }
610
611         return aHolder->StrictRunOrder();
612 }
613
614 //______________________________________________________________________________________________
615 void AliShuttleConfig::Print(Option_t* /*option*/) const
616 {
617 // print configuration
618         
619         TString result;
620         result += '\n';
621
622         result += Form("\nShuttle running on %s \n\n", fShuttleInstanceHost.Data());
623
624         if(fProcessAll) {
625                 result += Form("All detectors will be processed! \n\n");
626         } else {
627                 result += "Detectors processed by this host: ";
628                 TIter it(&fProcessedDetectors);
629                 TObjString* aDet;
630                 while ((aDet = (TObjString*) it.Next())) {
631                         result += Form("%s ", aDet->String().Data());
632                 }
633                 result += "\n\n";
634         }
635
636         result += Form("PP time out = %d - Max total retries = %d\n\n", fPPTimeOut, fMaxRetries);
637
638         result += Form("DAQ Logbook Configuration \n \tHost: %s; \tUser: %s; ",
639                 fDAQlbHost.Data(), fDAQlbUser.Data());
640
641 //      result += "Password: ";
642 //      result.Append('*', fDAQlbPass.Length());
643         result += Form("\tDB: %s; \tTable: %s",
644                 fDAQlbDB.Data(), fDAQlbTable.Data());
645
646         result += "\n\n";
647
648         for(int iSys=0;iSys<3;iSys++){
649                 result += Form("FXS Configuration for %s system\n", AliShuttleInterface::GetSystemName(iSys));
650                 result += Form("\tDB  host: %s; \tUser: %s; \tName: %s; \tTable: %s\n",
651                                                 fFXSdbHost[iSys].Data(), fFXSdbUser[iSys].Data(),
652                                                 fFXSdbName[iSys].Data(), fFXSdbTable[iSys].Data());
653                 // result += Form("DB Password:",fFXSdbPass[iSys].Data());
654                 result += Form("\tFXS host: %s; \tUser: %s\n\n", fFXSHost[iSys].Data(), fFXSUser[iSys].Data());
655                 // result += Form("FXS Password:",fFXSPass[iSys].Data());
656         }
657
658         TIter iter(fDetectorMap.GetTable());
659         TPair* aPair;
660         while ((aPair = (TPair*) iter.Next())) {
661                 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) aPair->Value();
662                 result += Form("Detector-specific configuration: *** %s *** \n", aHolder->GetDetector());
663                 result += Form("\tStrict run ordering flag: %s \n", aHolder->StrictRunOrder() ? "TRUE" : "FALSE");
664                 if(aHolder->SkipDCSQuery())
665                 {
666                         result += "\n";
667                         continue;
668                 }
669                 result += Form("\tAmanda server: %s:%d \n", aHolder->GetDCSHost(), aHolder->GetDCSPort());
670
671                 const TObjArray* aliases = aHolder->GetDCSAliases();
672                 if (aliases->GetEntries() != 0)
673                 {
674                         result += "\tDCS Aliases: ";
675                         TIter it(aliases);
676                         TObjString* anAlias;
677                         while ((anAlias = (TObjString*) it.Next()))
678                         {
679                                 result += Form("%s ", anAlias->String().Data());
680                         }
681                         result += "\n";
682                 }
683
684
685                 const TObjArray* dataPoints = aHolder->GetDCSDataPoints();
686                 if (dataPoints->GetEntries() != 0)
687                 {
688                         result += "\tDCS Data Points: ";
689                         TIter it(dataPoints);
690                         TObjString* aDataPoint;
691                         while ((aDataPoint = (TObjString*) it.Next())) {
692                                 result += Form("%s ", aDataPoint->String().Data());
693                         }
694                                 result += "\n";
695                 }
696                 result += "\n";
697                 
698         }
699
700         if(!fIsValid) result += "\n\n********** !!!!! Configuration is INVALID !!!!! **********\n";
701
702         AliInfo(result);
703 }