1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.15 2007/01/15 18:27:11 acolla
19 implementation of sending mail to subdetector expert in case the preprocessor fails.
20 shuttle.schema updated with expert's email entry
22 Revision 1.13 2006/12/07 08:51:26 jgrosseo
24 table, db names in ldap configuration
25 added GRP preprocessor
26 DCS data can also be retrieved by data point
28 Revision 1.12 2006/11/16 16:16:48 jgrosseo
29 introducing strict run ordering flag
30 removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
32 Revision 1.11 2006/11/06 14:23:04 jgrosseo
33 major update (Alberto)
34 o) reading of run parameters from the logbook
35 o) online offline naming conversion
36 o) standalone DCSclient package
38 Revision 1.10 2006/10/20 15:22:59 jgrosseo
39 o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
40 o) Merging Collect, CollectAll, CollectNew function
41 o) Removing implementation of empty copy constructors (declaration still there!)
43 Revision 1.9 2006/10/02 16:38:39 jgrosseo
46 storing of objects that failed to be stored to the grid before
47 interfacing of shuttle status table in daq system
49 Revision 1.8 2006/08/15 10:50:00 jgrosseo
50 effc++ corrections (alberto)
52 Revision 1.7 2006/07/20 09:54:40 jgrosseo
53 introducing status management: The processing per subdetector is divided into several steps,
54 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
55 can keep track of the number of failures and skips further processing after a certain threshold is
56 exceeded. These thresholds can be configured in LDAP.
58 Revision 1.6 2006/07/19 10:09:55 jgrosseo
59 new configuration, accesst to DAQ FES (Alberto)
61 Revision 1.5 2006/07/10 13:01:41 jgrosseo
62 enhanced storing of last sucessfully processed run (alberto)
64 Revision 1.4 2006/06/12 09:11:16 jgrosseo
65 coding conventions (Alberto)
67 Revision 1.3 2006/06/06 14:26:40 jgrosseo
68 o) removed files that were moved to STEER
69 o) shuttle updated to follow the new interface (Alberto)
71 Revision 1.7 2006/05/12 09:07:16 colla
73 New configuration complete
75 Revision 1.2 2006/03/07 07:52:34 hristov
76 New version (B.Yordanov)
78 Revision 1.4 2005/11/19 14:20:31 byordano
79 logbook config added to AliShuttleConfig
81 Revision 1.3 2005/11/17 19:24:25 byordano
82 TList changed to TObjArray in AliShuttleConfig
84 Revision 1.2 2005/11/17 14:43:23 byordano
87 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
88 Initial import as subdirectory in AliRoot
90 Revision 1.1.1.1 2005/09/12 22:11:40 byordano
93 Revision 1.3 2005/08/30 09:13:02 byordano
100 // This class keeps the AliShuttle configuration.
101 // It reads the configuration for LDAP server.
102 // For every child entry in basedn which has schema type 'shuttleConfig'
103 // it creates a detector configuration. This configuration includes:
104 // DCS server host and port and the set of aliases for which data from
105 // will be retrieved (used by AliShuttle).
109 #include "AliShuttleConfig.h"
110 #include "AliShuttleInterface.h"
115 #include <TObjString.h>
116 #include <TLDAPResult.h>
117 #include <TLDAPEntry.h>
118 #include <TLDAPAttribute.h>
121 AliShuttleConfig::AliShuttleConfigHolder::AliShuttleConfigHolder(const TLDAPEntry* entry):
129 fSkipDCSQuery(kFALSE),
130 fStrictRunOrder(kFALSE)
132 // constructor of the shuttle configuration holder
134 TLDAPAttribute* anAttribute;
135 fDCSAliases = new TObjArray();
136 fDCSAliases->SetOwner(1);
137 fDCSDataPoints = new TObjArray();
138 fDCSDataPoints->SetOwner(1);
139 fResponsibles = new TObjArray();
140 fResponsibles->SetOwner(1);
142 anAttribute = entry->GetAttribute("det"); // MUST
145 AliError(Form("Invalid configuration! No \"det\" attribute!"));
148 fDetector = anAttribute->GetValue();
150 anAttribute = entry->GetAttribute("StrictRunOrder"); // MAY
153 AliWarning(Form("%s did not set StrictRunOrder flag - the default is FALSE",
156 TString strictRunStr = anAttribute->GetValue();
157 if (!(strictRunStr == "0" || strictRunStr == "1"))
159 AliError("Invalid configuration! StrictRunOrder flag must be 0 or 1!");
162 fStrictRunOrder = (Bool_t) strictRunStr.Atoi();
165 anAttribute = entry->GetAttribute("responsible"); // MUST
168 AliError(Form("Invalid configuration! No \"responsible\" attribute!"));
171 const char* aResponsible;
172 while ((aResponsible = anAttribute->GetValue()))
174 fResponsibles->AddLast(new TObjString(aResponsible));
177 anAttribute = entry->GetAttribute("DCSHost"); // MAY
181 Form("%s has not DCS host entry - Shuttle will skip DCS data query!",
184 fSkipDCSQuery = kTRUE;
188 fDCSHost = anAttribute->GetValue();
190 anAttribute = entry->GetAttribute("DCSPort"); // MAY
193 AliError(Form("Invalid configuration! %s has DCS Host but no port number!",
197 TString portStr = anAttribute->GetValue();
198 fDCSPort = portStr.Atoi();
200 anAttribute = entry->GetAttribute("DCSalias"); // MAY
204 while ((anAlias = anAttribute->GetValue()))
206 ExpandAndAdd(fDCSAliases, anAlias);
210 anAttribute = entry->GetAttribute("DCSdatapoint"); // MAY
213 const char* aDataPoint;
214 while ((aDataPoint = anAttribute->GetValue()))
216 ExpandAndAdd(fDCSDataPoints, aDataPoint);
223 //______________________________________________________________________________________________
224 void AliShuttleConfig::AliShuttleConfigHolder::ExpandAndAdd(TObjArray* target, const char* entry)
227 // adds <entry> to <target> applying expanding of the name
228 // [N..M] creates M-N+1 names with the corresponding digits
231 TString entryStr(entry);
233 Int_t begin = entryStr.Index("[");
234 Int_t end = entryStr.Index("]");
235 if (begin != -1 && end != -1 && end > begin)
237 TString before(entryStr(0, begin));
238 TString after(entryStr(end+1, entryStr.Length()));
240 AliDebug(2, Form("Found [] pattern. Splitted input string %s %s", before.Data(), after.Data()));
242 Int_t dotdot = entryStr.Index("..");
244 TString nStr(entryStr(begin+1, dotdot-begin-1));
245 TString mStr(entryStr(dotdot+2, end-dotdot-2));
247 AliDebug(2, Form("Found [N..M] pattern. %s %s", nStr.Data(), mStr.Data()));
249 if (nStr.IsDigit() && mStr.IsDigit())
251 Int_t n = nStr.Atoi();
252 Int_t m = mStr.Atoi();
254 Int_t nDigits = nStr.Length();
256 formatStr.Form("%%s%%0%dd%%s", nDigits);
258 AliDebug(2, Form("Format string is %s", formatStr.Data()));
260 for (Int_t current = n; current<=m; ++current)
263 newEntry.Form(formatStr.Data(), before.Data(), current, after.Data());
265 AliDebug(2, Form("Calling recursive with %s", newEntry.Data()));
268 ExpandAndAdd(target, newEntry);
271 // return here because we processed the entries already recursively.
276 AliDebug(2, Form("Adding name %s", entry));
277 target->AddLast(new TObjString(entry));
280 //______________________________________________________________________________________________
281 AliShuttleConfig::AliShuttleConfigHolder::~AliShuttleConfigHolder()
283 // destructor of the shuttle configuration holder
286 delete fDCSDataPoints;
287 delete fResponsibles;
290 ClassImp(AliShuttleConfig)
292 //______________________________________________________________________________________________
293 AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
294 const char* binddn, const char* password, const char* basedn):
295 fIsValid(kFALSE), fConfigHost(host),
296 fDAQlbHost(""), fDAQlbPort(), fDAQlbUser(""), fDAQlbPass(""),
297 fDAQlbDB(""), fDAQlbTable(""),
298 fMaxRetries(0), fPPTimeOut(0), fDetectorMap(), fDetectorList(),
299 fShuttleInstanceHost(""), fProcessedDetectors(), fProcessAll(kFALSE)
302 // host: ldap server host
303 // port: ldap server port
304 // binddn: binddn used for ldap binding (simple bind is used!).
305 // password: password for binddn
306 // basedn: this is basedn whose childeren entries which have
307 // (objectClass=shuttleConfig) will be used as detector configurations.
310 fDetectorMap.SetOwner();
311 fDetectorList.SetOwner(0); //fDetectorList and fDetectorMap share the same object!
312 fProcessedDetectors.SetOwner();
314 TLDAPServer aServer(host, port, binddn, password, 3);
316 if (!aServer.IsConnected()) {
317 AliError(Form("Can't connect to ldap server %s:%d",
322 // reads configuration for the shuttle running on this machine
324 fShuttleInstanceHost = gSystem->HostName();
325 TString queryFilter = Form("(ShuttleHost=%s)", fShuttleInstanceHost.Data());
327 TLDAPResult* aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
330 AliError(Form("Can't find configuration with base DN: %s",
335 if (aResult->GetCount() == 0) {
336 AliError(Form("No Shuttle instance for host = %s!",
337 fShuttleInstanceHost.Data()));
338 AliError(Form("All detectors will be processed."));
342 if (aResult->GetCount() > 1) {
343 AliError(Form("More than one Shuttle instance for host %s!",
344 fShuttleInstanceHost.Data()));
349 TLDAPEntry* anEntry = 0;
350 TLDAPAttribute* anAttribute = 0;
353 anEntry = aResult->GetNext();
354 anAttribute = anEntry->GetAttribute("detectors");
356 while((detName = anAttribute->GetValue())){
357 TObjString *objDet= new TObjString(detName);
358 fProcessedDetectors.Add(objDet);
362 delete anEntry; delete aResult;
364 // Detector configuration (DCS Archive DB settings)
366 aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, "(objectClass=AliShuttleDetector)");
368 AliError(Form("Can't find configuration with base DN: %s", basedn));
373 while ((anEntry = aResult->GetNext())) {
374 AliShuttleConfigHolder* aHolder = new AliShuttleConfigHolder(anEntry);
377 if (!aHolder->IsValid()) {
378 AliError("Detector configuration error!");
384 TObjString* detStr = new TObjString(aHolder->GetDetector());
385 fDetectorMap.Add(detStr, aHolder);
386 fDetectorList.AddLast(detStr);
391 // Global configuration (DAQ logbook)
393 aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL,
394 "(objectClass=AliShuttleGlobalConfig)");
396 AliError(Form("Can't find configuration with base DN: %s",
401 if (aResult->GetCount() == 0) {
402 AliError("Can't find DAQ logbook configuration!");
407 if (aResult->GetCount() > 1) {
408 AliError("More than one DAQ logbook configuration found!");
413 anEntry = aResult->GetNext();
415 anAttribute = anEntry->GetAttribute("DAQLogbookHost");
417 AliError("Can't find DAQLogbookHost attribute!");
418 delete anEntry; delete aResult;
421 fDAQlbHost = anAttribute->GetValue();
423 anAttribute = anEntry->GetAttribute("DAQLogbookPort"); // MAY
426 fDAQlbPort = ((TString) anAttribute->GetValue()).Atoi();
428 fDAQlbPort = 3306; // mysql
431 anAttribute = anEntry->GetAttribute("DAQLogbookUser");
433 AliError("Can't find DAQLogbookUser attribute!");
434 delete aResult; delete anEntry;
437 fDAQlbUser = anAttribute->GetValue();
439 anAttribute = anEntry->GetAttribute("DAQLogbookPassword");
441 AliError("Can't find DAQLogbookPassword attribute!");
442 delete aResult; delete anEntry;
445 fDAQlbPass = anAttribute->GetValue();
447 anAttribute = anEntry->GetAttribute("DAQLogbookDB");
449 AliError("Can't find DAQLogbookDB attribute!");
450 delete aResult; delete anEntry;
453 fDAQlbDB = anAttribute->GetValue();
455 anAttribute = anEntry->GetAttribute("DAQLogbookTable");
457 AliError("Can't find DAQLogbookTable attribute!");
458 delete aResult; delete anEntry;
461 fDAQlbTable = anAttribute->GetValue();
464 anAttribute = anEntry->GetAttribute("MaxRetries");
466 AliError("Can't find MaxRetries attribute!");
467 delete aResult; delete anEntry;
470 TString tmpStr = anAttribute->GetValue();
471 fMaxRetries = tmpStr.Atoi();
473 anAttribute = anEntry->GetAttribute("PPTimeOut");
475 AliError("Can't find PPTimeOut attribute!");
476 delete aResult; delete anEntry;
479 tmpStr = anAttribute->GetValue();
480 fPPTimeOut = tmpStr.Atoi();
482 delete aResult; delete anEntry;
484 // FXS configuration (FXS logbook and hosts)
486 for(int iSys=0;iSys<3;iSys++){
487 queryFilter = Form("(system=%s)", AliShuttleInterface::GetSystemName(iSys));
488 aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
490 AliError(Form("Can't find configuration for system: %s",
491 AliShuttleInterface::GetSystemName(iSys)));
495 if (aResult->GetCount() != 1 ) {
496 AliError("Error in FXS configuration!");
501 anEntry = aResult->GetNext();
503 anAttribute = anEntry->GetAttribute("DBHost");
505 AliError(Form ("Can't find DBHost attribute for %s!!",
506 AliShuttleInterface::GetSystemName(iSys)));
507 delete aResult; delete anEntry;
510 fFXSdbHost[iSys] = anAttribute->GetValue();
512 anAttribute = anEntry->GetAttribute("DBPort"); // MAY
515 fFXSdbPort[iSys] = ((TString) anAttribute->GetValue()).Atoi();
517 fFXSdbPort[iSys] = 3306; // mysql
520 anAttribute = anEntry->GetAttribute("DBUser");
522 AliError(Form ("Can't find DBUser attribute for %s!!",
523 AliShuttleInterface::GetSystemName(iSys)));
524 delete aResult; delete anEntry;
527 fFXSdbUser[iSys] = anAttribute->GetValue();
529 anAttribute = anEntry->GetAttribute("DBPassword");
531 AliError(Form ("Can't find DBPassword attribute for %s!!",
532 AliShuttleInterface::GetSystemName(iSys)));
533 delete aResult; delete anEntry;
536 fFXSdbPass[iSys] = anAttribute->GetValue();
538 anAttribute = anEntry->GetAttribute("DBName");
540 AliError(Form ("Can't find DBName attribute for %s!!",
541 AliShuttleInterface::GetSystemName(iSys)));
542 delete aResult; delete anEntry;
546 fFXSdbName[iSys] = anAttribute->GetValue();
547 anAttribute = anEntry->GetAttribute("DBTable");
549 AliError(Form ("Can't find DBTable attribute for %s!!",
550 AliShuttleInterface::GetSystemName(iSys)));
551 delete aResult; delete anEntry;
554 fFXSdbTable[iSys] = anAttribute->GetValue();
556 anAttribute = anEntry->GetAttribute("FSHost");
558 AliError(Form ("Can't find FSHost attribute for %s!!",
559 AliShuttleInterface::GetSystemName(iSys)));
560 delete aResult; delete anEntry;
563 fFXSHost[iSys] = anAttribute->GetValue();
565 anAttribute = anEntry->GetAttribute("FSPort"); // MAY
568 fFXSPort[iSys] = ((TString) anAttribute->GetValue()).Atoi();
570 fFXSPort[iSys] = 22; // scp port number
573 anAttribute = anEntry->GetAttribute("FSUser");
575 AliError(Form ("Can't find FSUser attribute for %s!!",
576 AliShuttleInterface::GetSystemName(iSys)));
577 delete aResult; delete anEntry;
580 fFXSUser[iSys] = anAttribute->GetValue();
582 anAttribute = anEntry->GetAttribute("FSPassword");
583 if (anAttribute) fFXSPass[iSys] = anAttribute->GetValue();
585 delete aResult; delete anEntry;
591 //______________________________________________________________________________________________
592 AliShuttleConfig::~AliShuttleConfig()
596 fDetectorMap.DeleteAll();
597 fDetectorList.Clear();
598 fProcessedDetectors.Delete();
601 //______________________________________________________________________________________________
602 const TObjArray* AliShuttleConfig::GetDetectors() const
605 // returns collection of TObjString which contains the name
606 // of every detector which is in the configuration.
609 return &fDetectorList;
612 //______________________________________________________________________________________________
613 Bool_t AliShuttleConfig::HasDetector(const char* detector) const
616 // checks for paricular detector in the configuration.
618 return fDetectorMap.GetValue(detector) != NULL;
621 //______________________________________________________________________________________________
622 const char* AliShuttleConfig::GetDCSHost(const char* detector) const
625 // returns DCS server host used by particular detector
628 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
630 AliError(Form("There isn't configuration for detector: %s",
635 return aHolder->GetDCSHost();
638 //______________________________________________________________________________________________
639 Int_t AliShuttleConfig::GetDCSPort(const char* detector) const
642 // returns DCS server port used by particular detector
646 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
648 AliError(Form("There isn't configuration for detector: %s",
653 return aHolder->GetDCSPort();
656 //______________________________________________________________________________________________
657 const TObjArray* AliShuttleConfig::GetDCSAliases(const char* detector) const
660 // returns collection of TObjString which represents the set of aliases
661 // which used for data retrieval for particular detector
664 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
666 AliError(Form("There isn't configuration for detector: %s",
671 return aHolder->GetDCSAliases();
674 //______________________________________________________________________________________________
675 const TObjArray* AliShuttleConfig::GetDCSDataPoints(const char* detector) const
678 // returns collection of TObjString which represents the set of aliases
679 // which used for data retrieval for particular detector
682 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
684 AliError(Form("There isn't configuration for detector: %s",
689 return aHolder->GetDCSDataPoints();
692 //______________________________________________________________________________________________
693 const TObjArray* AliShuttleConfig::GetResponsibles(const char* detector) const
696 // returns collection of TObjString which represents the list of mail addresses
697 // of the detector's responsible(s)
700 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
702 AliError(Form("There isn't configuration for detector: %s",
707 return aHolder->GetResponsibles();
710 //______________________________________________________________________________________________
711 Bool_t AliShuttleConfig::HostProcessDetector(const char* detector) const
713 // return TRUE if detector is handled by host or if fProcessAll is TRUE
715 if(fProcessAll) return kTRUE;
716 TIter iter(&fProcessedDetectors);
718 while((detName = (TObjString*) iter.Next())){
719 if(detName->String() == detector) return kTRUE;
724 //______________________________________________________________________________________________
725 Bool_t AliShuttleConfig::StrictRunOrder(const char* detector) const
727 // return TRUE if detector wants strict run ordering of stored data
729 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
732 AliError(Form("There isn't configuration for detector: %s",
737 return aHolder->StrictRunOrder();
740 //______________________________________________________________________________________________
741 void AliShuttleConfig::Print(Option_t* /*option*/) const
743 // print configuration
748 result += "####################################################\n";
749 result += Form(" Shuttle configuration from %s \n", fConfigHost.Data());
750 result += "####################################################\n";
751 result += Form("\nShuttle running on %s \n", fShuttleInstanceHost.Data());
754 result += Form("All detectors will be processed! \n");
756 result += "Detectors processed by this host: ";
757 TIter it(&fProcessedDetectors);
759 while ((aDet = (TObjString*) it.Next())) {
760 result += Form("%s ", aDet->String().Data());
765 result += Form("PP time out = %d - Max total retries = %d\n\n", fPPTimeOut, fMaxRetries);
766 result += "------------------------------------------------------\n";
768 result += Form("Logbook Configuration \n\n \tHost: %s:%d; \tUser: %s; ",
769 fDAQlbHost.Data(), fDAQlbPort, fDAQlbUser.Data());
771 // result += "Password: ";
772 // result.Append('*', fDAQlbPass.Length());
773 result += Form("\tDB: %s; \tTable: %s",
774 fDAQlbDB.Data(), fDAQlbTable.Data());
778 result += "------------------------------------------------------\n";
779 result += "FXS configuration\n\n";
781 for(int iSys=0;iSys<3;iSys++){
782 result += Form("*** %s ***\n", AliShuttleInterface::GetSystemName(iSys));
783 result += Form("\tDB host: %s:%d; \tUser: %s; \tName: %s; \tTable: %s\n",
784 fFXSdbHost[iSys].Data(), fFXSdbPort[iSys], fFXSdbUser[iSys].Data(),
785 fFXSdbName[iSys].Data(), fFXSdbTable[iSys].Data());
786 // result += Form("DB Password:",fFXSdbPass[iSys].Data());
787 result += Form("\tFXS host: %s:%d; \tUser: %s\n\n", fFXSHost[iSys].Data(), fFXSPort[iSys],
788 fFXSUser[iSys].Data());
789 // result += Form("FXS Password:",fFXSPass[iSys].Data());
792 result += "------------------------------------------------------\n";
793 result += "Detector-specific configuration\n\n";
794 TIter iter(fDetectorMap.GetTable());
796 while ((aPair = (TPair*) iter.Next())) {
797 AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) aPair->Value();
798 result += Form("*** %s *** \n", aHolder->GetDetector());
800 const TObjArray* responsibles = aHolder->GetResponsibles();
801 if (responsibles->GetEntries() != 0)
803 result += "\tDetector responsible(s): ";
804 TIter it(responsibles);
805 TObjString* aResponsible;
806 while ((aResponsible = (TObjString*) it.Next()))
808 result += Form("%s ", aResponsible->String().Data());
813 result += Form("\tStrict run ordering: %s \n", aHolder->StrictRunOrder() ? "YES" : "NO");
814 if(aHolder->SkipDCSQuery())
819 result += Form("\tAmanda server: %s:%d \n", aHolder->GetDCSHost(), aHolder->GetDCSPort());
821 const TObjArray* aliases = aHolder->GetDCSAliases();
822 if (aliases->GetEntries() != 0)
824 result += "\tDCS Aliases: ";
827 while ((anAlias = (TObjString*) it.Next()))
829 result += Form("%s ", anAlias->String().Data());
834 const TObjArray* dataPoints = aHolder->GetDCSDataPoints();
835 if (dataPoints->GetEntries() != 0)
837 result += "\tDCS Data Points: ";
838 TIter it(dataPoints);
839 TObjString* aDataPoint;
840 while ((aDataPoint = (TObjString*) it.Next())) {
841 result += Form("%s ", aDataPoint->String().Data());
848 if(!fIsValid) result += "\n\n********** !!!!! Configuration is INVALID !!!!! **********\n";