]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - SHUTTLE/AliShuttleConfig.cxx
Little changes needed for running with new AliESDEvent
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttleConfig.cxx
index 3ff815957028d816b1e7f932fa997e3958b50632..28e5d4f73437fb318936d1081d077d57b7be4a03 100644 (file)
 
 /*
 $Log$
+Revision 1.20  2007/04/04 10:33:36  jgrosseo
+1) 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.
+In case of an error with the Grid, the Shuttle will retry the storing later, the preprocessor does not need to be run again.
+
+2) 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.
+
+3) New function StoreReferenceFile to _directly_ store a file (without opening it) to the reference storage.
+
+4) The memory usage of the preprocessor is monitored. If it exceeds 2 GB it is terminated.
+
+5) 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.
+If you always need DCS data (like before), you do not need to implement it.
+
+6) The run type has been added to the monitoring page
+
+Revision 1.19  2007/02/28 10:41:56  acolla
+Run type field added in SHUTTLE framework. Run type is read from "run type" logbook and retrieved by
+AliPreprocessor::GetRunType() function.
+Added some ldap definition files.
+
+Revision 1.18  2007/01/23 19:20:03  acolla
+Removed old ldif files, added TOF, MCH ldif files. Added some options in
+AliShuttleConfig::Print. Added in Ali Shuttle: SetShuttleTempDir and
+SetShuttleLogDir
+
+Revision 1.17  2007/01/18 11:17:47  jgrosseo
+changing spaces to tabs ;-)
+
+Revision 1.16  2007/01/18 11:10:35  jgrosseo
+adding the possibility of defining DCS alias and data points with patterns
+first pattern introduced: [N..M] to add all names between the two digits, this works also recursively.
+
+Revision 1.15  2007/01/15 18:27:11  acolla
+implementation of sending mail to subdetector expert in case the preprocessor fails.
+shuttle.schema updated with expert's email entry
+
+Revision 1.13  2006/12/07 08:51:26  jgrosseo
+update (alberto):
+table, db names in ldap configuration
+added GRP preprocessor
+DCS data can also be retrieved by data point
+
+Revision 1.12  2006/11/16 16:16:48  jgrosseo
+introducing strict run ordering flag
+removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
+
+Revision 1.11  2006/11/06 14:23:04  jgrosseo
+major update (Alberto)
+o) reading of run parameters from the logbook
+o) online offline naming conversion
+o) standalone DCSclient package
+
+Revision 1.10  2006/10/20 15:22:59  jgrosseo
+o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
+o) Merging Collect, CollectAll, CollectNew function
+o) Removing implementation of empty copy constructors (declaration still there!)
+
+Revision 1.9  2006/10/02 16:38:39  jgrosseo
+update (alberto):
+fixed memory leaks
+storing of objects that failed to be stored to the grid before
+interfacing of shuttle status table in daq system
+
+Revision 1.8  2006/08/15 10:50:00  jgrosseo
+effc++ corrections (alberto)
+
+Revision 1.7  2006/07/20 09:54:40  jgrosseo
+introducing status management: The processing per subdetector is divided into several steps,
+after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
+can keep track of the number of failures and skips further processing after a certain threshold is
+exceeded. These thresholds can be configured in LDAP.
+
+Revision 1.6  2006/07/19 10:09:55  jgrosseo
+new configuration, accesst to DAQ FES (Alberto)
+
+Revision 1.5  2006/07/10 13:01:41  jgrosseo
+enhanced storing of last sucessfully processed run (alberto)
+
 Revision 1.4  2006/06/12 09:11:16  jgrosseo
 coding conventions (Alberto)
 
@@ -61,6 +139,7 @@ some docs added
 
 
 #include "AliShuttleConfig.h"
+#include "AliShuttleInterface.h"
 
 #include "AliLog.h"
 
@@ -70,76 +149,184 @@ some docs added
 #include <TLDAPEntry.h>
 #include <TLDAPAttribute.h>
 
+
 AliShuttleConfig::AliShuttleConfigHolder::AliShuttleConfigHolder(const TLDAPEntry* entry):
-       fIsValid(kFALSE)
+fDetector(""),
+fDCSHost(""),
+fDCSPort(0),
+fDCSAliases(0),
+fDCSDataPoints(0),
+fDCSAliasesComp(0),
+fDCSDataPointsComp(0),
+fResponsibles(0),
+fIsValid(kFALSE),
+fSkipDCSQuery(kFALSE),
+fStrictRunOrder(kFALSE)
 {
 // constructor of the shuttle configuration holder
 
        TLDAPAttribute* anAttribute;
-       
-       anAttribute = entry->GetAttribute("det");
-       if (!anAttribute) {
-               AliError("Invalid configuration! Can't get detector name.");
+       fDCSAliases = new TObjArray();
+       fDCSAliases->SetOwner(1);
+       fDCSDataPoints = new TObjArray();
+       fDCSDataPoints->SetOwner(1);
+       fDCSAliasesComp = new TObjArray();
+       fDCSAliasesComp->SetOwner(1);
+       fDCSDataPointsComp = new TObjArray();
+       fDCSDataPointsComp->SetOwner(1);
+       fResponsibles = new TObjArray();
+       fResponsibles->SetOwner(1);
+
+       anAttribute = entry->GetAttribute("det"); // MUST
+        if (!anAttribute)
+       {
+               AliError(Form("Invalid configuration! No \"det\" attribute!"));
                return;
-       }
+        }
        fDetector = anAttribute->GetValue();
-       if (!fDetector.Length()) {
-               AliError("Detector name can't be an empty string!")
-               return;
+
+       anAttribute = entry->GetAttribute("StrictRunOrder"); // MAY
+        if (!anAttribute)
+       {
+               AliWarning(Form("%s did not set StrictRunOrder flag - the default is FALSE",
+                               fDetector.Data()));
+        } else {
+               TString strictRunStr = anAttribute->GetValue();
+               if (!(strictRunStr == "0" || strictRunStr == "1"))
+               {
+                       AliError("Invalid configuration! StrictRunOrder flag must be 0 or 1!");
+                       return;
+               }
+               fStrictRunOrder = (Bool_t) strictRunStr.Atoi();
        }
 
-       anAttribute = entry->GetAttribute("DCSHost");
-       if (!anAttribute) {
-               AliError("Invalid configuration! Can't get DCSHost.");
-               return;
+       anAttribute = entry->GetAttribute("responsible"); // MAY
+        if (!anAttribute)
+       {
+               AliDebug(2, "Warning! No \"responsible\" attribute!");
+        }
+       else
+       {
+               const char* aResponsible;
+               while ((aResponsible = anAttribute->GetValue()))
+               {
+                       fResponsibles->AddLast(new TObjString(aResponsible));
+               }
        }
-       fDCSHost = anAttribute->GetValue();
-       if (!fDCSHost.Length()) {
-               AliError("Host can't be an empty string!")
+       
+       anAttribute = entry->GetAttribute("DCSHost"); // MAY
+       if (!anAttribute)
+       {
+               AliDebug(2,
+                       Form("%s has not DCS host entry - Shuttle will skip DCS data query!",
+                               fDetector.Data()));
+               fIsValid = kTRUE;
+               fSkipDCSQuery = kTRUE;
                return;
        }
 
-       anAttribute = entry->GetAttribute("DCSPort");
-        if (!anAttribute) {
-               AliError("Invalid configuration! Can't get DCSPort.");
+       fDCSHost = anAttribute->GetValue();
+
+       anAttribute = entry->GetAttribute("DCSPort"); // MAY
+        if (!anAttribute)
+       {
+               AliError(Form("Invalid configuration! %s has DCS Host but no port number!",
+                               fDetector.Data()));
                return;
         }
        TString portStr = anAttribute->GetValue();
-       if (!portStr.Length()) {
-               AliError("port can't be an empty string!")
-               return;
-       }
        fDCSPort = portStr.Atoi();
 
-       anAttribute = entry->GetAttribute("DCSAlias");
-        if (!anAttribute) {
-               AliError("Invalid configuration! Can't get alias attribute.");
-               return;
-       }
-       const char* anAlias;
-       while ((anAlias = anAttribute->GetValue())) {
-               fDCSAliases.AddLast(new TObjString(anAlias));
+       anAttribute = entry->GetAttribute("DCSalias"); // MAY
+        if (anAttribute)
+       {
+               const char* anAlias;
+               while ((anAlias = anAttribute->GetValue()))
+               {
+                       fDCSAliasesComp->AddLast(new TObjString(anAlias));
+                       ExpandAndAdd(fDCSAliases, anAlias);
+               }
        }
 
-       anAttribute = entry->GetAttribute("DAQFileIDs");
-        if (!anAttribute) {
-               AliError("Invalid configuration! Can't get DAQFileIDs attribute.");
-               return;
-       }
-       const char* aFileID;
-       while ((aFileID = anAttribute->GetValue())) {
-               fDAQFileIDs.AddLast(new TObjString(aFileID));
+       anAttribute = entry->GetAttribute("DCSdatapoint"); // MAY
+        if (anAttribute)
+       {
+               const char* aDataPoint;
+               while ((aDataPoint = anAttribute->GetValue()))
+               {
+               fDCSDataPointsComp->AddLast(new TObjString(aDataPoint));
+               ExpandAndAdd(fDCSDataPoints, aDataPoint);
+               }
        }
-               
+
        fIsValid = kTRUE;
 }
 
+//______________________________________________________________________________________________
+void AliShuttleConfig::AliShuttleConfigHolder::ExpandAndAdd(TObjArray* target, const char* entry)
+{
+       //
+       // adds <entry> to <target> applying expanding of the name
+       // [N..M] creates M-N+1 names with the corresponding digits
+       //
+
+       TString entryStr(entry);
+
+       Int_t begin = entryStr.Index("[");
+       Int_t end = entryStr.Index("]");
+       if (begin != -1 && end != -1 && end > begin)
+       {
+               TString before(entryStr(0, begin));
+               TString after(entryStr(end+1, entryStr.Length()));
+
+               AliDebug(2, Form("Found [] pattern. Splitted input string %s %s", before.Data(), after.Data()));
+
+               Int_t dotdot = entryStr.Index("..");
+
+               TString nStr(entryStr(begin+1, dotdot-begin-1));
+               TString mStr(entryStr(dotdot+2, end-dotdot-2));
+
+               AliDebug(2, Form("Found [N..M] pattern. %s %s", nStr.Data(), mStr.Data()));
+
+               if (nStr.IsDigit() && mStr.IsDigit())
+               {
+                       Int_t n = nStr.Atoi();
+                       Int_t m = mStr.Atoi();
+
+                       Int_t nDigits = nStr.Length();
+                       TString formatStr;
+                       formatStr.Form("%%s%%0%dd%%s", nDigits);
+
+                       AliDebug(2, Form("Format string is %s", formatStr.Data()));
+
+                       for (Int_t current = n; current<=m; ++current)
+                       {
+                               TString newEntry;
+                               newEntry.Form(formatStr.Data(), before.Data(), current, after.Data());
+
+                               AliDebug(2, Form("Calling recursive with %s", newEntry.Data()));
+
+                               // and go recursive
+                               ExpandAndAdd(target, newEntry);
+                       }
+
+                       // return here because we processed the entries already recursively.
+                       return;
+               }
+       }
+
+       AliDebug(2, Form("Adding name %s", entry));
+       target->AddLast(new TObjString(entry));
+}
+
 //______________________________________________________________________________________________
 AliShuttleConfig::AliShuttleConfigHolder::~AliShuttleConfigHolder()
 {
 // destructor of the shuttle configuration holder
 
-       fDCSAliases.Delete();
+       delete fDCSAliases;
+       delete fDCSDataPoints;
+       delete fResponsibles;
 }
 
 ClassImp(AliShuttleConfig)
@@ -147,8 +334,11 @@ ClassImp(AliShuttleConfig)
 //______________________________________________________________________________________________
 AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
        const char* binddn, const char* password, const char* basedn):
-       fIsValid(kFALSE),
-       fProcessAll(kFALSE)
+       fIsValid(kFALSE), fConfigHost(host),
+       fDAQlbHost(""), fDAQlbPort(), fDAQlbUser(""), fDAQlbPass(""),
+       fDAQlbDB(""), fDAQlbTable(""), fShuttlelbTable(""), fRunTypelbTable(""),
+       fMaxRetries(0), fPPTimeOut(0), fPPMaxMem(0), fDetectorMap(), fDetectorList(),
+       fShuttleInstanceHost(""), fProcessedDetectors(), fProcessAll(kFALSE)
 {
        //
        // host: ldap server host
@@ -159,23 +349,24 @@ AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
        // (objectClass=shuttleConfig) will be used as detector configurations.
        //
 
+       fDetectorMap.SetOwner();
+       fDetectorList.SetOwner(0); //fDetectorList and fDetectorMap share the same object!
+       fProcessedDetectors.SetOwner();
+
        TLDAPServer aServer(host, port, binddn, password, 3);
-       
+
        if (!aServer.IsConnected()) {
-               AliError(Form("Can't connect to ldap server %s:%d", 
+               AliError(Form("Can't connect to ldap server %s:%d",
                                host, port));
                return;
        }
 
        // reads configuration for the shuttle running on this machine
-       
+
        fShuttleInstanceHost = gSystem->HostName();
-       TString queryFilter = "(ShuttleHost=";
-       queryFilter += fShuttleInstanceHost;
-       queryFilter += ")";     
-       
-       TLDAPResult* aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL,
-                       queryFilter.Data());
+       TString queryFilter = Form("(ShuttleHost=%s)", fShuttleInstanceHost.Data());
+
+       TLDAPResult* aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
 
        if (!aResult) {
                AliError(Form("Can't find configuration with base DN: %s",
@@ -184,18 +375,21 @@ AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
        }
 
        if (aResult->GetCount() == 0) {
-               AliError(Form("No Shuttle instance for host = %s!",fShuttleInstanceHost.Data()));
+               AliError(Form("No Shuttle instance for host = %s!",
+                                       fShuttleInstanceHost.Data()));
                AliError(Form("All detectors will be processed."));
                fProcessAll=kTRUE;
        }
 
        if (aResult->GetCount() > 1) {
-               AliError(Form("More than one Shuttle instance for host %s!",fShuttleInstanceHost.Data()));
+               AliError(Form("More than one Shuttle instance for host %s!",
+                                       fShuttleInstanceHost.Data()));
+               delete aResult;
                return;
        }
-       
-       TLDAPEntry* anEntry;
-       TLDAPAttribute* anAttribute;
+
+       TLDAPEntry* anEntry = 0;
+       TLDAPAttribute* anAttribute = 0;
 
        if(!fProcessAll){
                anEntry = aResult->GetNext();
@@ -207,32 +401,36 @@ AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
                }
        }
 
-       aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL,
-                       "(objectClass=AliShuttleDetector)");
+       delete anEntry; delete aResult;
+
+       // Detector configuration (DCS Archive DB settings)
+
+       aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, "(objectClass=AliShuttleDetector)");
        if (!aResult) {
-               AliError(Form("Can't find configuration with base DN: %s",
-                               basedn));
+               AliError(Form("Can't find configuration with base DN: %s", basedn));
                return;
        }
 
+
        while ((anEntry = aResult->GetNext())) {
                AliShuttleConfigHolder* aHolder = new AliShuttleConfigHolder(anEntry);
                delete anEntry;
 
                if (!aHolder->IsValid()) {
-                       AliError("This entry is going to be skipped!");
+                       AliError("Detector configuration error!");
                        delete aHolder;
-
-                       continue;
+                       delete aResult;
+                       return;
                }
 
                TObjString* detStr = new TObjString(aHolder->GetDetector());
                fDetectorMap.Add(detStr, aHolder);
                fDetectorList.AddLast(detStr);
-       }       
-       
+       }
+
        delete aResult;
 
+       // Global configuration (DAQ logbook)
 
        aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL,
                        "(objectClass=AliShuttleGlobalConfig)");
@@ -244,47 +442,215 @@ AliShuttleConfig::AliShuttleConfig(const char* host, Int_t port,
 
        if (aResult->GetCount() == 0) {
                AliError("Can't find DAQ logbook configuration!");
+               delete aResult;
                return;
        }
 
        if (aResult->GetCount() > 1) {
                AliError("More than one DAQ logbook configuration found!");
+               delete aResult;
                return;
        }
 
        anEntry = aResult->GetNext();
-       
+
        anAttribute = anEntry->GetAttribute("DAQLogbookHost");
        if (!anAttribute) {
                AliError("Can't find DAQLogbookHost attribute!");
+               delete anEntry; delete aResult;
                return;
        }
-       fDAQLogBookHost = anAttribute->GetValue();
+       fDAQlbHost = anAttribute->GetValue();
+
+       anAttribute = anEntry->GetAttribute("DAQLogbookPort"); // MAY
+       if (anAttribute)
+       {
+               fDAQlbPort = ((TString) anAttribute->GetValue()).Atoi();
+       } else {
+               fDAQlbPort = 3306; // mysql
+       }
 
        anAttribute = anEntry->GetAttribute("DAQLogbookUser");
        if (!anAttribute) {
                AliError("Can't find DAQLogbookUser attribute!");
+               delete aResult; delete anEntry;
                return;
        }
-       fDAQLogBookUser = anAttribute->GetValue();
-       
+       fDAQlbUser = anAttribute->GetValue();
+
        anAttribute = anEntry->GetAttribute("DAQLogbookPassword");
        if (!anAttribute) {
                AliError("Can't find DAQLogbookPassword attribute!");
+               delete aResult; delete anEntry;
                return;
        }
-       fDAQLogBookPassword = anAttribute->GetValue();
+       fDAQlbPass = anAttribute->GetValue();
 
-       anAttribute = anEntry->GetAttribute("DAQFileSystemHost");
+       anAttribute = anEntry->GetAttribute("DAQLogbookDB");
        if (!anAttribute) {
-               AliError("Can't find DAQFileSystemHost attribute!");
+               AliError("Can't find DAQLogbookDB attribute!");
+               delete aResult; delete anEntry;
                return;
        }
-       fDAQFSHost = anAttribute->GetValue();
+       fDAQlbDB = anAttribute->GetValue();
 
-       delete anEntry;
-       delete aResult;
+       anAttribute = anEntry->GetAttribute("DAQLogbookTable");
+       if (!anAttribute) {
+               AliError("Can't find DAQLogbookTable attribute!");
+               delete aResult; delete anEntry;
+               return;
+       }
+       fDAQlbTable = anAttribute->GetValue();
+
+       anAttribute = anEntry->GetAttribute("ShuttleLogbookTable");
+       if (!anAttribute) {
+               AliError("Can't find ShuttleLogbookTable attribute!");
+               delete aResult; delete anEntry;
+               return;
+       }
+       fShuttlelbTable = anAttribute->GetValue();
+
+       anAttribute = anEntry->GetAttribute("RunTypeLogbookTable");
+       if (!anAttribute) {
+               AliError("Can't find RunTypeLogbookTable attribute!");
+               delete aResult; delete anEntry;
+               return;
+       }
+       fRunTypelbTable = anAttribute->GetValue();
+
+       anAttribute = anEntry->GetAttribute("MaxRetries");
+       if (!anAttribute) {
+               AliError("Can't find MaxRetries attribute!");
+               delete aResult; delete anEntry;
+               return;
+       }
+       TString tmpStr = anAttribute->GetValue();
+       fMaxRetries = tmpStr.Atoi();
+
+       anAttribute = anEntry->GetAttribute("PPTimeOut");
+       if (!anAttribute) {
+               AliError("Can't find PPTimeOut attribute!");
+               delete aResult; delete anEntry;
+               return;
+       }
+       tmpStr = anAttribute->GetValue();
+       fPPTimeOut = tmpStr.Atoi();
+
+       anAttribute = anEntry->GetAttribute("PPMaxMem");
+       if (!anAttribute) {
+               AliError("Can't find PPMaxMem attribute!");
+               delete aResult; delete anEntry;
+               return;
+       }
+       tmpStr = anAttribute->GetValue();
+       fPPMaxMem = tmpStr.Atoi();
        
+       delete aResult; delete anEntry;
+
+       // FXS configuration (FXS logbook and hosts)
+
+       for(int iSys=0;iSys<3;iSys++){
+               queryFilter = Form("(system=%s)", AliShuttleInterface::GetSystemName(iSys));
+               aResult = aServer.Search(basedn, LDAP_SCOPE_ONELEVEL, queryFilter.Data());
+               if (!aResult) {
+                       AliError(Form("Can't find configuration for system: %s",
+                                       AliShuttleInterface::GetSystemName(iSys)));
+                       return;
+               }
+
+               if (aResult->GetCount() != 1 ) {
+                       AliError("Error in FXS configuration!");
+                       delete aResult;
+                       return;
+               }
+
+               anEntry = aResult->GetNext();
+
+               anAttribute = anEntry->GetAttribute("DBHost");
+               if (!anAttribute) {
+                       AliError(Form ("Can't find DBHost attribute for %s!!",
+                                               AliShuttleInterface::GetSystemName(iSys)));
+                       delete aResult; delete anEntry;
+                       return;
+               }
+               fFXSdbHost[iSys] = anAttribute->GetValue();
+
+               anAttribute = anEntry->GetAttribute("DBPort"); // MAY
+               if (anAttribute)
+               {
+                       fFXSdbPort[iSys] = ((TString) anAttribute->GetValue()).Atoi();
+               } else {
+                       fFXSdbPort[iSys] = 3306; // mysql
+               }
+
+               anAttribute = anEntry->GetAttribute("DBUser");
+               if (!anAttribute) {
+                       AliError(Form ("Can't find DBUser attribute for %s!!",
+                                               AliShuttleInterface::GetSystemName(iSys)));
+                       delete aResult; delete anEntry;
+                       return;
+               }
+               fFXSdbUser[iSys] = anAttribute->GetValue();
+
+               anAttribute = anEntry->GetAttribute("DBPassword");
+               if (!anAttribute) {
+                       AliError(Form ("Can't find DBPassword attribute for %s!!",
+                                               AliShuttleInterface::GetSystemName(iSys)));
+                       delete aResult; delete anEntry;
+                       return;
+               }
+               fFXSdbPass[iSys] = anAttribute->GetValue();
+
+               anAttribute = anEntry->GetAttribute("DBName");
+               if (!anAttribute) {
+                       AliError(Form ("Can't find DBName attribute for %s!!",
+                                               AliShuttleInterface::GetSystemName(iSys)));
+                       delete aResult; delete anEntry;
+                       return;
+               }
+
+               fFXSdbName[iSys] = anAttribute->GetValue();
+               anAttribute = anEntry->GetAttribute("DBTable");
+               if (!anAttribute) {
+                       AliError(Form ("Can't find DBTable attribute for %s!!",
+                                               AliShuttleInterface::GetSystemName(iSys)));
+                       delete aResult; delete anEntry;
+                       return;
+               }
+               fFXSdbTable[iSys] = anAttribute->GetValue();
+
+               anAttribute = anEntry->GetAttribute("FSHost");
+               if (!anAttribute) {
+                       AliError(Form ("Can't find FSHost attribute for %s!!",
+                                               AliShuttleInterface::GetSystemName(iSys)));
+                       delete aResult; delete anEntry;
+                       return;
+               }
+               fFXSHost[iSys] = anAttribute->GetValue();
+
+               anAttribute = anEntry->GetAttribute("FSPort"); // MAY
+               if (anAttribute)
+               {
+                       fFXSPort[iSys] = ((TString) anAttribute->GetValue()).Atoi();
+               } else {
+                       fFXSPort[iSys] = 22; // scp port number
+               }
+
+               anAttribute = anEntry->GetAttribute("FSUser");
+               if (!anAttribute) {
+                       AliError(Form ("Can't find FSUser attribute for %s!!",
+                                               AliShuttleInterface::GetSystemName(iSys)));
+                       delete aResult; delete anEntry;
+                       return;
+               }
+               fFXSUser[iSys] = anAttribute->GetValue();
+
+               anAttribute = anEntry->GetAttribute("FSPassword");
+               if (anAttribute) fFXSPass[iSys] = anAttribute->GetValue();
+
+               delete aResult; delete anEntry;
+       }
+
        fIsValid = kTRUE;
 }
 
@@ -294,6 +660,8 @@ AliShuttleConfig::~AliShuttleConfig()
 // destructor
 
        fDetectorMap.DeleteAll();
+       fDetectorList.Clear();
+       fProcessedDetectors.Delete();
 }
 
 //______________________________________________________________________________________________
@@ -370,10 +738,10 @@ const TObjArray* AliShuttleConfig::GetDCSAliases(const char* detector) const
 }
 
 //______________________________________________________________________________________________
-const TObjArray* AliShuttleConfig::GetDAQFileIDs(const char* detector) const
+const TObjArray* AliShuttleConfig::GetDCSDataPoints(const char* detector) const
 {
        //
-       // returns collection of TObjString which represents the set of DAQ file IDs
+       // returns collection of TObjString which represents the set of aliases
        // which used for data retrieval for particular detector
        //
 
@@ -384,7 +752,25 @@ const TObjArray* AliShuttleConfig::GetDAQFileIDs(const char* detector) const
                 return NULL;
         }
 
-       return aHolder->GetDAQFileIDs();
+       return aHolder->GetDCSDataPoints();
+}
+
+//______________________________________________________________________________________________
+const TObjArray* AliShuttleConfig::GetResponsibles(const char* detector) const
+{
+       //
+       // returns collection of TObjString which represents the list of mail addresses
+       // of the detector's responsible(s)
+       //
+
+       AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
+        if (!aHolder) {
+                AliError(Form("There isn't configuration for detector: %s",
+                        detector));
+                return NULL;
+        }
+
+       return aHolder->GetResponsibles();
 }
 
 //______________________________________________________________________________________________
@@ -402,79 +788,151 @@ Bool_t AliShuttleConfig::HostProcessDetector(const char* detector) const
 }
 
 //______________________________________________________________________________________________
-void AliShuttleConfig::Print(Option_t* /*option*/) const 
+Bool_t AliShuttleConfig::StrictRunOrder(const char* detector) const
+{
+       // return TRUE if detector wants strict run ordering of stored data
+
+       AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) fDetectorMap.GetValue(detector);
+        if (!aHolder)
+       {
+                AliError(Form("There isn't configuration for detector: %s",
+                        detector));
+                return kTRUE;
+        }
+
+       return aHolder->StrictRunOrder();
+}
+
+//______________________________________________________________________________________________
+void AliShuttleConfig::Print(Option_t* option) const
 {
 // print configuration
-       
+// options : "": print configuration for all detectors, aliases and DPs in compacted format
+//          "uncompact": print configuration for all detectors, aliases and DPs in uncompacted format
+//          "DET": print configuration for DET, aliases and DPs in compacted format
+//          "DET, uncompact": print configuration for DET, aliases and DPs in uncompacted format
+
        TString result;
        result += '\n';
 
-       result += "Shuttle running on host: ";
-       result += fShuttleInstanceHost;
-       result += '\n';
-       result += "Detectors handled by this host: ";
-       TIter it(&fProcessedDetectors);
-       TObjString* aDet;
-       while ((aDet = (TObjString*) it.Next())) {
-               result += aDet->String();
-               result += ' ';
+       result += "####################################################\n";
+       result += Form(" Shuttle configuration from %s \n", fConfigHost.Data());
+       result += "####################################################\n";
+       result += Form("\nShuttle running on %s \n", fShuttleInstanceHost.Data());
+
+       if(fProcessAll) {
+               result += Form("All detectors will be processed! \n");
+       } else {
+               result += "Detectors processed by this host: ";
+               TIter it(&fProcessedDetectors);
+               TObjString* aDet;
+               while ((aDet = (TObjString*) it.Next())) {
+                       result += Form("%s ", aDet->String().Data());
+               }
+               result += "\n";
        }
-       result += '\n';
-       if(fProcessAll) result += "ProcessAll is ON";
 
-       result += '\n';
-       result += '\n';
+       result += Form("PP time out = %d - Max PP memsize = %d KB - Max total retries = %d\n\n", fPPTimeOut, fPPMaxMem, fMaxRetries);
+       result += "------------------------------------------------------\n";
 
-       result += "DAQ LogBook Host: ";
-       result += fDAQLogBookHost;
-       result += '\n';
-       result += "DAQ LogBook User: ";
-       result += fDAQLogBookUser;
-       result += '\n';
-       result += "DAQ LogBook Password: ";
-       result.Append('*', fDAQLogBookPassword.Length());
-       result += '\n';
-       result += '\n';
-       result += "DAQ File System Host: ";
-       result += fDAQFSHost;
-       result += '\n';
+       result += Form("Logbook Configuration \n\n \tHost: %s:%d; \tUser: %s; ",
+               fDAQlbHost.Data(), fDAQlbPort, fDAQlbUser.Data());
+
+//     result += "Password: ";
+//     result.Append('*', fDAQlbPass.Length());
+       result += Form("\tDB: %s; \tTables: %s, %s, %s",
+               fDAQlbDB.Data(), fDAQlbTable.Data(), fShuttlelbTable.Data(), fRunTypelbTable.Data());
+
+       result += "\n\n";
+
+       result += "------------------------------------------------------\n";
+       result += "FXS configuration\n\n";
+
+       for(int iSys=0;iSys<3;iSys++){
+               result += Form("*** %s ***\n", AliShuttleInterface::GetSystemName(iSys));
+               result += Form("\tDB  host: %s:%d; \tUser: %s; \tName: %s; \tTable: %s\n",
+                                               fFXSdbHost[iSys].Data(), fFXSdbPort[iSys], fFXSdbUser[iSys].Data(),
+                                               fFXSdbName[iSys].Data(), fFXSdbTable[iSys].Data());
+               // result += Form("DB Password:",fFXSdbPass[iSys].Data());
+               result += Form("\tFXS host: %s:%d; \tUser: %s\n\n", fFXSHost[iSys].Data(), fFXSPort[iSys],
+                                               fFXSUser[iSys].Data());
+               // result += Form("FXS Password:",fFXSPass[iSys].Data());
+       }
 
+       TString optStr(option);
+
+       result += "------------------------------------------------------\n";
+       result += "Detector-specific configuration\n\n";
        TIter iter(fDetectorMap.GetTable());
        TPair* aPair;
        while ((aPair = (TPair*) iter.Next())) {
                AliShuttleConfigHolder* aHolder = (AliShuttleConfigHolder*) aPair->Value();
-               result += '\n';
-               result += " Detector: ";
-               result += aHolder->GetDetector();
-               result += '\n'; 
-               result += " DCS Host: ";
-               result += aHolder->GetDCSHost();
-               result += '\n';
-               result += " DCS Port: ";
-               result += aHolder->GetDCSPort();
-               result += '\n';
-
-               result += " DCS Aliases: ";
-               const TObjArray* aliases = aHolder->GetDCSAliases();    
-               TIter it(aliases);
-               TObjString* anAlias;    
-               while ((anAlias = (TObjString*) it.Next())) {
-                       result += anAlias->String();
-                       result += ' ';
-               }       
-               
-               result += '\n';
-
-               result += " DAQ File IDs: ";
-               const TObjArray* fileIDs = aHolder->GetDAQFileIDs();    
-               TIter it2(fileIDs);             
-               TObjString* aFileID;    
-               while ((aFileID = (TObjString*) it2.Next())) {
-                       result += aFileID->String();
-                       result += ' ';
-               }       
-               result += '\n';
+               if (option != 0 && !optStr.Contains(aHolder->GetDetector()) && optStr.CompareTo("uncompact",TString::kIgnoreCase) != 0 )
+                               continue;
+               result += Form("*** %s *** \n", aHolder->GetDetector());
+
+               const TObjArray* responsibles = aHolder->GetResponsibles();
+               if (responsibles->GetEntries() != 0)
+               {
+                       result += "\tDetector responsible(s): ";
+                       TIter it(responsibles);
+                       TObjString* aResponsible;
+                       while ((aResponsible = (TObjString*) it.Next()))
+                       {
+                               result += Form("%s ", aResponsible->String().Data());
+                       }
+                       result += "\n";
+               }
+
+               result += Form("\tStrict run ordering: %s \n", aHolder->StrictRunOrder() ? "YES" : "NO");
+               if(aHolder->SkipDCSQuery())
+               {
+                       result += "\n";
+                       continue;
+               }
+               result += Form("\tAmanda server: %s:%d \n", aHolder->GetDCSHost(), aHolder->GetDCSPort());
+
+               const TObjArray* aliases = 0;
+               if (optStr.Contains("uncompact",TString::kIgnoreCase))
+               {
+                       aliases = aHolder->GetDCSAliases();
+               } else {
+                       aliases = aHolder->GetCompactDCSAliases();
+               }
+
+               if (aliases->GetEntries() != 0)
+               {
+                       result += "\tDCS Aliases: ";
+                       TIter it(aliases);
+                       TObjString* anAlias;
+                       while ((anAlias = (TObjString*) it.Next()))
+                       {
+                               result += Form("%s ", anAlias->String().Data());
+                       }
+                       result += "\n";
+               }
+
+               const TObjArray* dataPoints = 0;
+               if (optStr.Contains("uncompact",TString::kIgnoreCase))
+               {
+                       dataPoints = aHolder->GetDCSDataPoints();
+               } else {
+                       dataPoints = aHolder->GetCompactDCSDataPoints();
+               }
+               if (dataPoints->GetEntries() != 0)
+               {
+                       result += "\tDCS Data Points: ";
+                       TIter it(dataPoints);
+                       TObjString* aDataPoint;
+                       while ((aDataPoint = (TObjString*) it.Next())) {
+                               result += Form("%s ", aDataPoint->String().Data());
+                       }
+                               result += "\n";
+               }
+               result += "\n";
        }
 
+       if(!fIsValid) result += "\n\n********** !!!!! Configuration is INVALID !!!!! **********\n";
+
        AliInfo(result);
 }