0a9d16cd3c441def1607f7f87b4207e8457f7dd0
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttleTrigger.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.1  2006/03/07 07:52:34  hristov
19  New version (B.Yordanov)
20
21  Revision 1.5  2005/11/21 09:03:48  byordano
22  one more print added
23
24  Revision 1.4  2005/11/20 10:12:37  byordano
25  comments added to AliShuttleTrigger
26
27  */
28
29
30 // 
31 // This class is to deal with DAQ LogBook and DAQ "end of run" notification.
32 // It has severeal two modes:
33 //      1) syncrhnized - Collect(), CollectNew() and CollectAll methods
34 //      2) asynchronized - Run() - starts listening for DAQ "end of run"
35 //              notification by DIM service.
36 //
37
38 #include "AliShuttleTrigger.h"
39
40 #include <TSQLServer.h>
41 #include <TSQLResult.h>
42 #include <TSQLRow.h>
43 #include <TObjArray.h>
44 #include <TSystem.h>
45
46 #include "AliLog.h"
47 #include "AliCDBManager.h"
48 #include "AliCDBStorage.h"
49 #include "AliCDBEntry.h"
50
51 #include "AliSimpleValue.h"
52 #include "AliShuttleConfig.h"
53 #include "AliShuttle.h"
54 #include "DATENotifier.h"
55
56 ClassImp(TerminateSignalHandler)
57
58 //______________________________________________________________________________________________
59 Bool_t TerminateSignalHandler::Notify() {
60
61         AliInfo("Terminate signal received ...");
62         fTrigger->Terminate();
63
64         return kTRUE;
65 }
66
67 ClassImp(AliShuttleTrigger)
68
69 //______________________________________________________________________________________________
70 AliShuttleTrigger::AliShuttleTrigger(const AliShuttleConfig* config,
71                 UInt_t timeout, Int_t retries):
72         fConfig(config), fShuttle(NULL),
73         fNotified(kFALSE), fTerminate(kFALSE), fCondition(&fMutex),
74         fQuitSignalHandler(this, kSigQuit), 
75         fInterruptSignalHandler(this, kSigInterrupt)
76 {
77         //
78         // config - pointer to the AliShuttleConfig object which represents
79         // the configuration
80         // mainStorage - pointer to AliCDBStorage for the undelying CDBStorage
81         // localStorage (local) CDB storage to be used if mainStorage is unavailable
82         //
83
84         fShuttle = new AliShuttle(config, timeout, retries);
85
86         gSystem->AddSignalHandler(&fQuitSignalHandler);
87         gSystem->AddSignalHandler(&fInterruptSignalHandler);
88 }
89
90 //______________________________________________________________________________________________
91 AliShuttleTrigger::~AliShuttleTrigger() {
92
93         gSystem->RemoveSignalHandler(&fQuitSignalHandler);
94         gSystem->RemoveSignalHandler(&fInterruptSignalHandler);
95
96         delete fShuttle;
97 }
98
99 //______________________________________________________________________________________________
100 Bool_t AliShuttleTrigger::Notify() {
101         //
102         // Trigger CollectNew() methods in asynchronized (listen) mode.
103         // Usually called automaticly by DATENotifier on "end of run" 
104         // notification event.
105         //
106
107         fMutex.Lock();
108
109         fNotified = kTRUE;
110         fCondition.Signal();
111
112         fMutex.UnLock();
113
114         return kTRUE;
115 }
116
117 //______________________________________________________________________________________________
118 void AliShuttleTrigger::Terminate() {
119         //
120         // Stop triggers listen mode and exist from Run()
121         // Usually called automaticly by TerminateSignalHandler.
122         //
123
124         fTerminate = kTRUE;
125         fCondition.Signal();
126 }
127
128 //______________________________________________________________________________________________
129 void AliShuttleTrigger::Run() {
130         //
131         // AliShuttleTrigger main loop for asynchronized (listen) mode.
132         // It spawns DIM service listener and waits for DAQ "end of run"
133         // notification. Calls CollectNew() on notification.
134         //
135
136         fTerminate = kFALSE;
137
138         DATENotifier* notifier = new DATENotifier(this, "/DATE/LOGBOOK/UPDATE");
139
140         while (1) {
141         
142                 fMutex.Lock();
143
144                 while (!(fNotified || fTerminate)) {
145                         fCondition.Wait();
146                 }
147
148                 fNotified = kFALSE;
149                 
150                 fMutex.UnLock();
151
152                 if (fTerminate) {
153                         AliInfo("Terminated.");
154                         break;          
155                 }
156         
157                 CollectNew();
158         }
159
160         delete notifier;
161 }
162
163 //______________________________________________________________________________________________
164 Bool_t AliShuttleTrigger::RetrieveDATEEntries(const char* whereClause,
165                 TObjArray& entries, Int_t& lastRun) {
166
167         TString sqlQuery;
168         sqlQuery += "select run, time_start, time_end from logbook ";
169         sqlQuery += whereClause;
170         sqlQuery += " order by run";
171
172         TSQLServer* aServer;
173         TString logbookHost="mysql://";
174         logbookHost+=fConfig->GetDAQLogBookHost();
175         
176         aServer = TSQLServer::Connect(logbookHost,
177                         fConfig->GetDAQLogBookUser(),
178                         fConfig->GetDAQLogBookPassword());
179         if (!aServer) {
180                 AliError("Can't establish connection to DAQ log book DB!");
181                 return kFALSE;
182         }
183         
184         aServer->GetTables("REFSYSLOG");
185
186         TSQLResult* aResult;
187         aResult = aServer->Query(sqlQuery);
188         if (!aResult) {
189                 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
190                 delete aServer;
191                 return kFALSE;
192         }
193
194         if (aResult->GetFieldCount() != 3) {
195                 AliError("Invalid SQL result field number!");
196                 delete aResult;
197                 delete aServer;
198                 return kFALSE;
199         }
200
201         lastRun = 0;
202
203         TSQLRow* aRow;
204         while ((aRow = aResult->Next())) {
205                 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
206                 Int_t run = runString.Atoi();
207
208                 TString startTimeString(aRow->GetField(1),
209                                 aRow->GetFieldLength(1));
210                 Int_t startTime = startTimeString.Atoi();
211                 if (!startTime) {
212                         AliWarning(Form("Zero StartTime for run <%d>!", run));
213                         AliWarning("Going to skip this run!");
214                         continue;
215                 }
216
217                 TString endTimeString(aRow->GetField(2),
218                                 aRow->GetFieldLength(2));
219                 Int_t endTime = endTimeString.Atoi();
220                 if (!endTime) {
221                         AliWarning(Form("Zero EndTime for run <%d>!", run));
222                         AliWarning("Going to skip this run!");
223                         continue;
224                 }
225
226                 if (startTime > endTime) {
227                         AliWarning(Form("StartTime bigger than EndTime for run <%d>", run));
228                         AliWarning("Going to skip this run!");
229                         continue;
230                 }
231
232                 entries.AddLast(new DATEEntry(run, startTime, endTime));
233                 if (lastRun < run) {
234                         lastRun = run;
235                 }
236                 delete aRow;
237         }
238
239         delete aResult;
240         
241         aServer->Shutdown();
242         delete aServer;
243
244         entries.SetOwner(1);
245
246         return kTRUE;
247 }
248
249 //______________________________________________________________________________________________
250 Bool_t AliShuttleTrigger::RetrieveConditionsData(const TObjArray& dateEntries) {
251
252         Bool_t hasError = kFALSE;
253
254         TIter iter(&dateEntries);
255         DATEEntry* anEntry;
256         while ((anEntry = (DATEEntry*) iter.Next())) {
257                 if(!fShuttle->Process(anEntry->GetRun(),
258                                 anEntry->GetStartTime(),
259                                 anEntry->GetEndTime())) {
260                         hasError = kTRUE;
261                 }
262         }
263
264         return !hasError;
265 }
266
267 //______________________________________________________________________________________________
268 Bool_t AliShuttleTrigger::Collect(Int_t run) {
269         //
270         // Collects conditions date for the given run.
271         //
272
273         AliInfo(Form("Collecting conditions data for run <%d> ...", run));
274
275         TString whereClause("where run = ");
276         whereClause += run;
277
278         Int_t lastRun;
279         TObjArray dateEntries;
280         if (!RetrieveDATEEntries(whereClause, dateEntries, lastRun)) {
281                 AliError("Can't retrieve entries from DAQ log book.");
282                 return kFALSE;
283         }
284
285         if (!dateEntries.GetEntriesFast()) {
286                 AliError(Form("There isn't entry for run <%d> in DAQ log book!",
287                         run));
288                 return kFALSE;
289         }
290
291         if (dateEntries.GetEntriesFast() > 1) {
292                 AliError(Form("There is more than one entry for run <%d> in DAQ log book", run));
293                 return kFALSE;
294         }
295
296         if (!RetrieveConditionsData(dateEntries)) {
297                 AliError("An error occured during conditions data retrieval!");
298                 return kFALSE;
299         }
300
301         return kTRUE;
302 }
303
304 //______________________________________________________________________________________________
305 Bool_t AliShuttleTrigger::CollectNew() {
306         //
307         // Collects conditions data for all new run written to DAQ LogBook.
308         //
309
310         AliInfo("Collecting conditions data for new runs ...");
311
312         Int_t lastRun;
313
314         AliCDBEntry* cdbEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
315                                 ->Get("/SHUTTLE/SYSTEM/LASTRUN", 0);
316         if (cdbEntry) {
317                 TObject* anObject = cdbEntry->GetObject();
318                 if (anObject == NULL ||
319                         anObject->IsA() != AliSimpleValue::Class()) {
320                         AliError("Invalid last run object stored to CDB!");
321                         return kFALSE;
322                 }
323                 AliSimpleValue* simpleValue = (AliSimpleValue*) anObject;
324                 lastRun = simpleValue->GetInt();
325                 delete cdbEntry;
326         } else {
327                 AliWarning("There isn't last run stored! Starting from run 21200");
328                 lastRun = 21200;
329         }
330
331         AliInfo(Form("Last run number <%d>", lastRun));
332
333         TString whereClause("where run > ");
334         whereClause += lastRun;
335
336         Int_t newLastRun;
337         TObjArray dateEntries;
338         if (!RetrieveDATEEntries(whereClause, dateEntries, newLastRun)) {
339                 AliError("Can't retrieve entries from DAQ log book.");
340                 return kFALSE;
341         }
342
343         if (newLastRun > lastRun) {
344                 AliSimpleValue lastRunObj(newLastRun);
345                 AliCDBMetaData metaData;
346                 AliCDBId cdbID(AliCDBPath("SHUTTLE", "SYSTEM", "LASTRUN"), 0, 0);
347
348                 UInt_t result = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalURI())
349                                 ->Put(&lastRunObj, cdbID, &metaData);
350
351                 if (!result) {
352                         AliError("Can't store last run to CDB!");
353                         return kFALSE;
354                 }
355         }
356
357         if (!RetrieveConditionsData(dateEntries)) {
358                 AliError("An error occured during conditions data retrieval!");
359                 return kFALSE;
360         }
361
362         return kTRUE;
363 }
364
365 //______________________________________________________________________________________________
366 Bool_t AliShuttleTrigger::CollectAll() {
367         //
368         // Collects conditions data for all run written in DAQ LogBook.
369         //
370
371         AliInfo("Collecting conditions data for all runs ...");
372
373         Int_t lastRun;
374         TObjArray dateEntries;
375         if (!RetrieveDATEEntries("", dateEntries, lastRun)) {
376                 AliError("Can't retrieve entries from DAQ log book.");
377                 return kFALSE;
378         }
379
380         if (!RetrieveConditionsData(dateEntries)) {
381                 AliError("An error occured during conditions data retrieval!");
382                 return kFALSE;
383         }
384
385         return kTRUE;
386 }
387