]> git.uio.no Git - u/mrichter/AliRoot.git/blob - SHUTTLE/AliDCSClient.cxx
adding DCS, HLT FES to the configuration
[u/mrichter/AliRoot.git] / SHUTTLE / AliDCSClient.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.3  2006/06/12 09:11:16  jgrosseo
19 coding conventions (Alberto)
20
21 Revision 1.2  2006/03/07 07:52:34  hristov
22 New version (B.Yordanov)
23
24 Revision 1.3  2005/11/17 17:47:34  byordano
25 TList changed to TObjArray
26
27 Revision 1.2  2005/11/17 14:43:23  byordano
28 import to local CVS
29
30 Revision 1.1.1.1  2005/10/28 07:33:58  hristov
31 Initial import as subdirectory in AliRoot
32
33 Revision 1.1.1.1  2005/09/12 22:11:40  byordano
34 SHUTTLE package
35
36 Revision 1.3  2005/08/30 10:53:23  byordano
37 some more descriptions added
38
39 */
40
41 //
42 // This class represents the AliDCSClient.
43 // The client used for data retrieval from DCS server.
44 // There are two way for retrieving data from the server.
45 //      1) asking for DP (DataPoint) - usually changed frequently.
46 //      2) asking for Alias (Alias) - alias should be the same through whole
47 //              experimnet.
48 //              
49 // There are two type of read operations:
50 //      Asking for single alias/dp or asking for set of aliases/dp
51 //
52 // In case of ServerError the coresponding error code and 
53 // error string (description) could be got by GetServerErrorCode() and
54 // GetServerErrorString()
55 //
56
57 #include "AliDCSClient.h"
58 #include "AliDCSValue.h"
59 #include "AliLog.h"
60
61 #include <TSocket.h>
62 #include <TObjArray.h>
63 #include <TMap.h>
64 #include <TObjString.h>
65 #include <TSystem.h>
66
67 ClassImp(AliDCSClient)
68
69 const Int_t AliDCSClient::fgkBadState;
70 const Int_t AliDCSClient::fgkInvalidParameter;
71 const Int_t AliDCSClient::fgkTimeout;
72 const Int_t AliDCSClient::fgkBadMessage;
73 const Int_t AliDCSClient::fgkCommError;
74 const Int_t AliDCSClient::fgkServerError;
75
76 const char* AliDCSClient::fgkBadStateString = "BadState";
77 const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
78 const char* AliDCSClient::fgkTimeoutString = "Timeout";
79 const char* AliDCSClient::fgkBadMessageString = "BadMessage";
80 const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
81 const char* AliDCSClient::fgkServerErrorString = "ServerError";
82
83 //______________________________________________________________________
84 AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
85         Int_t retries):
86         fSocket(NULL), fTimeout(timeout), fRetries(retries),
87         fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
88 {
89         // 
90         // host: DCS server host
91         // port: DCS server port
92         // timeout: in case of communication error or socket read/write this 
93         //              timeout will be used before the next try is made. 
94         // retries: the number of retries after which the connection is 
95         //              is considered as invalid and error is returned.
96         //
97
98         Int_t tries = 0;        
99         
100         while (tries < fRetries) {
101                 fSocket = new TSocket(host, port);
102                 if (fSocket->IsValid()) {
103                         AliDebug(1, Form("Connected to %s:%d", host, port));
104                         fSocket->SetOption(kNoBlock, 1);
105                         break;
106                 }
107                 
108                 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
109
110                 delete fSocket;
111                 fSocket = NULL;
112
113                 gSystem->Sleep(fTimeout);
114                 tries ++;
115         }
116 }
117
118 //______________________________________________________________________
119 AliDCSClient::AliDCSClient(const AliDCSClient& /*other*/):
120 TObject()
121 {
122 // copy constructor (not implemented)
123
124 }
125
126 //______________________________________________________________________
127 AliDCSClient &AliDCSClient::operator=(const AliDCSClient& /*other*/)
128 {
129 // assignment operator (not implemented)
130
131 return *this;
132 }
133
134 //______________________________________________________________________
135 AliDCSClient::~AliDCSClient() 
136 {
137 // destructor
138
139         if (fSocket) {
140                 Close();
141                 delete fSocket;
142         }
143 }
144
145 //______________________________________________________________________
146 Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size) 
147 {
148 // send buffer containing the message to the DCS server
149
150         Int_t sentSize = 0;
151         Int_t tries = 0;
152
153         while (sentSize < size && tries < fRetries) {
154
155                 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
156
157                 if (sResult == 0) {
158                         AliDebug(1, Form("Timeout! tries <%d> ...", tries));
159                         tries ++;
160                         continue;
161
162                 } else if (sResult < 0) {
163                         AliDebug(1, Form("Communication error <%d>!", 
164                                         fSocket->GetErrorCode()));
165                         return AliDCSClient::fgkCommError;
166                 }
167
168                 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
169                                         kDontBlock);
170
171                 if (sResult > 0) {
172                         sentSize += sResult;
173                 } else {
174                         AliDebug(1, Form("Communication error <%d>!",
175                                         fSocket->GetErrorCode()));
176                         return AliDCSClient::fgkCommError;
177                 }
178         }
179
180         if (tries == fRetries) {
181                 return AliDCSClient::fgkTimeout;
182         }
183
184         return sentSize;
185 }
186
187 //______________________________________________________________________
188 Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size) 
189 {
190 // Receive message from the DCS server and fill buffer
191
192         Int_t receivedSize = 0;
193         Int_t tries = 0;
194
195         while (receivedSize < size && tries < fRetries) {
196
197                 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
198
199                 if (sResult == 0) {
200                         AliDebug(1, Form("Timeout! tries <%d> ...", tries));
201                         tries ++;
202                         continue;
203
204                 } else if (sResult < 0) {
205                         AliDebug(1, Form("Communication error <%d>",
206                                         fSocket->GetErrorCode()));
207                         return AliDCSClient::fgkCommError;
208                 }
209
210                 sResult = fSocket->RecvRaw(buffer + receivedSize, 
211                         size - receivedSize, kDontBlock);
212
213                 if (sResult > 0) {
214                         receivedSize += sResult;
215                 } else {
216                         AliDebug(1, Form("Communication error <%d>",
217                                         fSocket->GetErrorCode()));
218                         return AliDCSClient::fgkCommError;
219                 }
220         }
221
222         if (tries == fRetries) {
223                 return AliDCSClient::fgkTimeout;
224         }
225
226         return receivedSize;
227 }
228
229 //______________________________________________________________________
230 Int_t AliDCSClient::SendMessage(AliDCSMessage& message) 
231 {
232 // send message to the DCS server
233
234         message.StoreToBuffer();
235
236         AliDebug(2, "Sending message.\n"); 
237         message.Print();
238
239         return SendBuffer(message.GetMessage(), message.GetMessageSize());
240 }
241
242 //______________________________________________________________________
243 Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message) 
244 {
245 // receive message from the DCS server
246         
247         char header[HEADER_SIZE];
248
249         Int_t sResult;
250
251         if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
252                 AliDebug(1, Form("Can't receive message header! Reason: %s", 
253                         GetErrorString(sResult)));
254                 return sResult;
255         }
256
257         if (!message.SetRawHeader(header)) {
258                 return AliDCSClient::fgkBadMessage;
259         }
260
261         if ((sResult = ReceiveBuffer(message.GetBody(), 
262                         message.GetBodySize())) < 0) {
263                 
264                 AliDebug(1, Form("Can't receive message body! Reason: %s", 
265                         GetErrorString(sResult)));
266                 return sResult;
267         }
268
269         message.LoadFromBuffer();
270
271         AliDebug(2, "Message received.");
272         message.Print();
273
274         return HEADER_SIZE + sResult;
275 }
276
277 //______________________________________________________________________
278 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
279         const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray& result) 
280 {
281 // get array of DCS values from the DCS server
282 // reqString: alias name
283 // startTime, endTime: start time and end time of the query
284 // result: contains the array of retrieved AliDCSValue's
285
286         if (!IsConnected()) {
287                 AliError("Not connected!");
288                 return AliDCSClient::fgkBadState;
289         }
290
291         Int_t sResult;
292         AliDCSMessage requestMessage;
293         requestMessage.CreateRequestMessage(reqType, startTime, endTime, 
294                         reqString);
295
296         if ((sResult = SendMessage(requestMessage)) < 0) {
297                 AliError(Form("Can't send request message! Reason: %s",
298                         GetErrorString(sResult)));
299                 Close();
300                 return sResult;
301         }       
302         
303         sResult = ReceiveValueSet(result);
304         
305         Close();
306
307         return sResult;
308 }
309
310 //______________________________________________________________________
311 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
312         UInt_t startTime, UInt_t endTime, TMap& result) 
313 {
314 // get array of DCS values from the DCS server
315 // startTime, endTime: start time and end time of the query
316 // result: map containing the array of alias names. It will be filled with
317 // the values retrieved for each alias
318
319         if (!IsConnected()) {
320                 AliError("Not connected!");
321                 return AliDCSClient::fgkBadState;
322         }       
323
324         AliDCSMessage multiRequestMessage;
325         multiRequestMessage.CreateMultiRequestMessage(reqType, 
326                         startTime, endTime);
327
328         TObjArray requests;
329         
330         TIter iter(&result);
331         TObjString* aRequest;
332         
333         // copy request strings to temporary TObjArray because
334         // TMap doesn't guarantee the order of elements!!!
335         while ((aRequest = (TObjString*) iter.Next())) {
336                 requests.AddLast(aRequest);
337                 if (!multiRequestMessage.AddRequestString(aRequest->String()))
338                 {
339                         return AliDCSClient::fgkInvalidParameter;
340                 }
341         }
342
343         Int_t sResult;
344         if ((sResult = SendMessage(multiRequestMessage)) < 0) {
345                 AliError(Form("Can't send request message! Reason: %s",
346                         GetErrorString(sResult)));
347                 Close();
348                 return sResult;
349         }
350
351         result.SetOwner(0);
352         result.Clear();
353
354         TIter reqIter(&requests);
355         while ((aRequest = (TObjString*) reqIter.Next())) {
356                 TObjArray* resultSet = new TObjArray();
357                 resultSet->SetOwner(1);
358
359                 if ((sResult = ReceiveValueSet(*resultSet)) < 0) {
360                         AliError(Form("Can't get values for %s!" ,
361                                 aRequest->String().Data()));
362
363                         delete resultSet;
364                         break;
365                 }
366
367                 result.Add(aRequest, resultSet);
368         }
369
370         if (sResult < 0) {
371                 result.DeleteValues();
372                 result.Clear();
373
374                 requests.Delete();
375         } else {
376                 result.SetOwner(1);
377         }
378
379         Close();
380
381         return sResult;
382 }
383         
384 //______________________________________________________________________
385 Int_t AliDCSClient::ReceiveValueSet(TObjArray& result)
386 {
387 // receive set of values 
388
389         Int_t sResult;
390
391         AliDCSMessage responseMessage;
392         if ((sResult = ReceiveMessage(responseMessage)) < 0) {
393                 AliError(Form("Can't receive response message! Reason: %s",
394                         GetErrorString(sResult)));
395                 return sResult;
396         }       
397
398         UInt_t valueCount;
399
400         if (responseMessage.GetType() == AliDCSMessage::kCount) {
401                 valueCount = responseMessage.GetCount();
402
403         } else if (responseMessage.GetType() == AliDCSMessage::kError) {
404                 fServerErrorCode = responseMessage.GetErrorCode();
405                 fServerError = responseMessage.GetErrorString();
406
407                 return AliDCSClient::fgkServerError;
408
409         } else {
410                 AliError("Bad message type received!"); 
411                 return AliDCSClient::fgkBadMessage;
412         }
413
414         UInt_t receivedValues = 0;
415
416         AliDCSValue::Type valueType = AliDCSValue::kInvalid;
417
418         while (receivedValues < valueCount) {
419
420                 AliDCSMessage message;
421
422                 if ((sResult = ReceiveMessage(message)) < 0) {
423                         AliError(Form("Can't receive message! Reason: %s",
424                                 GetErrorString(sResult)));
425                         return sResult;
426                 }
427
428                 if (message.GetType() == AliDCSMessage::kResultSet) {
429
430                         if (valueType == AliDCSValue::kInvalid) {
431                                 valueType = message.GetValueType();
432                         } else {
433                                 if (valueType != message.GetValueType()) {
434                                         AliError("Unexpected value type!");
435                                         return AliDCSClient::fgkBadMessage;
436                                 }
437                         }
438                         
439                         receivedValues += message.GetValues(result);
440
441                         if (receivedValues > valueCount) {
442                                 AliError("Message contains more values than expected!");
443                                 return AliDCSClient::fgkBadMessage;
444                         }
445
446                 } else if (message.GetType() == AliDCSMessage::kError) {
447                                 fServerErrorCode = 
448                                         responseMessage.GetErrorCode();
449                                 fServerError = responseMessage.GetErrorString();
450
451                                 return AliDCSClient::fgkServerError;
452                 } else {
453                         AliError("Bad message type received!");
454                         return AliDCSClient::fgkBadMessage;
455                 }       
456         }       
457         
458         return receivedValues;
459 }
460                 
461 //______________________________________________________________________
462 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
463                                 UInt_t endTime, TObjArray& result)
464 {
465         //
466         // Reads a values from the server which correspond to this
467         // DataPoint (dpName) in time interval (startTime - endTime).
468         // result: Collection of AliDCSValue which contains the read values.
469         //
470         // Returns:
471         //      If >= 0 , the number of values read.
472         //      if < 0, the error code which has occured during the read.
473         //
474
475         return GetValues(AliDCSMessage::kDPName, 
476                         dpName, startTime, endTime, result);
477 }
478
479 //______________________________________________________________________
480 Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
481                                 UInt_t endTime, TObjArray& result)
482 {
483         //
484         // Reads a values from the server which correspond to this
485         // alias (alias) in time interval (startTime - endTime).
486         // result: Collection of AliDCSValue which contains the read values.
487         //
488         // Returns:
489         //      If >= 0 , the number of values read.
490         //      if < 0, the error code which has occured during the read.
491         //
492
493         return GetValues(AliDCSMessage::kAlias, 
494                         alias, startTime, endTime, result);
495 }
496
497 //______________________________________________________________________
498 Int_t AliDCSClient::GetDPValues(UInt_t startTime, UInt_t endTime, 
499                                 TMap& result) 
500 {
501         //
502         // For every key of 'result' (which must be TObjString) 
503         // reads a valueSet. The key represents particular DataPoint to be read.
504         // For all DataPoints time interval (startTime - endTime) is used.
505         // After the read, the correspoding value for every key is a 
506         // TObjArray - collection of AliDCSValue, or result is an empty map in
507         // case of error.
508         // 
509         // Returns:
510         //      If >= 0 , the number of values read.
511         //      if < 0, the error code which has occured during the read.
512         //
513
514         return GetValues(AliDCSMessage::kDPName, startTime, endTime, result);
515 }
516
517 //______________________________________________________________________
518 Int_t AliDCSClient::GetAliasValues(UInt_t startTime, UInt_t endTime,
519                                 TMap& result) 
520 {
521         //
522         // For every key of 'result' (which must be TObjString) 
523         // reads a valueSet. The key represents particular Alias to be read.
524         // For all aliases time interval (startTime - endTime) is used.
525         // After the read, the correspoding value for every key is a 
526         // TObjArray - collection of AliDCSValue, or result is an empty map in
527         // case of error.
528         // 
529         // Returns:
530         //      If >= 0 , the number of values read.
531         //      if < 0, the error code which has occured during the read.
532         //
533
534         return GetValues(AliDCSMessage::kAlias, startTime, endTime, result);
535 }
536
537 //______________________________________________________________________
538 Bool_t AliDCSClient::IsConnected() 
539 {
540         //
541         // Returns kTRUE if there is a valid connection to the server.
542         //
543
544         if (fSocket) {
545                 return fSocket->IsValid();
546         }
547
548         return kFALSE;
549 }
550
551 //______________________________________________________________________
552 void AliDCSClient::Close() 
553 {
554         //
555         // Close the connection.
556         //
557
558         if (fSocket) {
559                 fSocket->Close();
560         }
561 }
562
563 //______________________________________________________________________
564 const char* AliDCSClient::GetErrorString(Int_t code) 
565 {
566         //
567         // Returns a short string describing the error code.
568         // code: the error code.
569         //
570         
571
572         switch (code) {
573                 case AliDCSClient::fgkBadState:
574                         return AliDCSClient::fgkBadStateString;
575
576                 case AliDCSClient::fgkInvalidParameter:
577                         return AliDCSClient::fgkInvalidParameterString;
578
579                 case AliDCSClient::fgkTimeout:
580                         return AliDCSClient::fgkTimeoutString;
581
582                 case AliDCSClient::fgkBadMessage:
583                         return AliDCSClient::fgkBadMessageString;
584         
585                 case AliDCSClient::fgkCommError:
586                         return AliDCSClient::fgkCommErrorString;
587
588                 case AliDCSClient::fgkServerError:
589                         return AliDCSClient::fgkServerErrorString;
590
591                 default:
592                         AliErrorGeneral("AliDCSClient::GetErrorString",
593                                 "Unknown error code!");
594                         return "UnknownCode";
595         }
596 }
597