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