1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.4 2006/07/04 14:59:57 jgrosseo
19 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
21 Revision 1.3 2006/06/12 09:11:16 jgrosseo
22 coding conventions (Alberto)
24 Revision 1.2 2006/03/07 07:52:34 hristov
25 New version (B.Yordanov)
27 Revision 1.3 2005/11/17 17:47:34 byordano
28 TList changed to TObjArray
30 Revision 1.2 2005/11/17 14:43:23 byordano
33 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
34 Initial import as subdirectory in AliRoot
36 Revision 1.1.1.1 2005/09/12 22:11:40 byordano
39 Revision 1.3 2005/08/30 10:53:23 byordano
40 some more descriptions added
45 // This class represents the AliDCSClient.
46 // The client used for data retrieval from DCS server.
47 // There are two way for retrieving data from the server.
48 // 1) asking for DP (DataPoint) - usually changed frequently.
49 // 2) asking for Alias (Alias) - alias should be the same through whole
52 // There are two type of read operations:
53 // Asking for single alias/dp or asking for set of aliases/dp
55 // In case of ServerError the coresponding error code and
56 // error string (description) could be got by GetServerErrorCode() and
57 // GetServerErrorString()
60 #include "AliDCSClient.h"
61 #include "AliDCSValue.h"
65 #include <TObjArray.h>
67 #include <TObjString.h>
70 ClassImp(AliDCSClient)
72 const Int_t AliDCSClient::fgkBadState;
73 const Int_t AliDCSClient::fgkInvalidParameter;
74 const Int_t AliDCSClient::fgkTimeout;
75 const Int_t AliDCSClient::fgkBadMessage;
76 const Int_t AliDCSClient::fgkCommError;
77 const Int_t AliDCSClient::fgkServerError;
79 const char* AliDCSClient::fgkBadStateString = "BadState";
80 const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
81 const char* AliDCSClient::fgkTimeoutString = "Timeout";
82 const char* AliDCSClient::fgkBadMessageString = "BadMessage";
83 const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
84 const char* AliDCSClient::fgkServerErrorString = "ServerError";
86 //______________________________________________________________________
87 AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
89 fSocket(NULL), fTimeout(timeout), fRetries(retries),
90 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
93 // host: DCS server host
94 // port: DCS server port
95 // timeout: in case of communication error or socket read/write this
96 // timeout will be used before the next try is made.
97 // retries: the number of retries after which the connection is
98 // is considered as invalid and error is returned.
103 while (tries < fRetries) {
104 fSocket = new TSocket(host, port);
105 if (fSocket->IsValid()) {
106 AliDebug(1, Form("Connected to %s:%d", host, port));
107 fSocket->SetOption(kNoBlock, 1);
111 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
116 gSystem->Sleep(fTimeout);
121 //______________________________________________________________________
122 AliDCSClient::AliDCSClient(const AliDCSClient& /*other*/):
123 TObject(), fSocket(NULL), fTimeout(0), fRetries(0),
124 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
127 // copy constructor (not implemented)
131 //______________________________________________________________________
132 AliDCSClient &AliDCSClient::operator=(const AliDCSClient& /*other*/)
134 // assignment operator (not implemented)
139 //______________________________________________________________________
140 AliDCSClient::~AliDCSClient()
150 //______________________________________________________________________
151 Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size)
153 // send buffer containing the message to the DCS server
158 while (sentSize < size && tries < fRetries) {
160 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
163 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
167 } else if (sResult < 0) {
168 AliDebug(1, Form("Communication error <%d>!",
169 fSocket->GetErrorCode()));
170 return AliDCSClient::fgkCommError;
173 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
179 AliDebug(1, Form("Communication error <%d>!",
180 fSocket->GetErrorCode()));
181 return AliDCSClient::fgkCommError;
185 if (tries == fRetries) {
186 return AliDCSClient::fgkTimeout;
192 //______________________________________________________________________
193 Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size)
195 // Receive message from the DCS server and fill buffer
197 Int_t receivedSize = 0;
200 while (receivedSize < size && tries < fRetries) {
202 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
205 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
209 } else if (sResult < 0) {
210 AliDebug(1, Form("Communication error <%d>",
211 fSocket->GetErrorCode()));
212 return AliDCSClient::fgkCommError;
215 sResult = fSocket->RecvRaw(buffer + receivedSize,
216 size - receivedSize, kDontBlock);
219 receivedSize += sResult;
221 AliDebug(1, Form("Communication error <%d>",
222 fSocket->GetErrorCode()));
223 return AliDCSClient::fgkCommError;
227 if (tries == fRetries) {
228 return AliDCSClient::fgkTimeout;
234 //______________________________________________________________________
235 Int_t AliDCSClient::SendMessage(AliDCSMessage& message)
237 // send message to the DCS server
239 message.StoreToBuffer();
241 AliDebug(2, "Sending message.\n");
244 return SendBuffer(message.GetMessage(), message.GetMessageSize());
247 //______________________________________________________________________
248 Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message)
250 // receive message from the DCS server
252 char header[HEADER_SIZE];
256 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
257 AliDebug(1, Form("Can't receive message header! Reason: %s",
258 GetErrorString(sResult)));
262 if (!message.SetRawHeader(header)) {
263 return AliDCSClient::fgkBadMessage;
266 if ((sResult = ReceiveBuffer(message.GetBody(),
267 message.GetBodySize())) < 0) {
269 AliDebug(1, Form("Can't receive message body! Reason: %s",
270 GetErrorString(sResult)));
274 message.LoadFromBuffer();
276 AliDebug(2, "Message received.");
279 return HEADER_SIZE + sResult;
282 //______________________________________________________________________
283 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
284 const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray& result)
286 // get array of DCS values from the DCS server
287 // reqString: alias name
288 // startTime, endTime: start time and end time of the query
289 // result: contains the array of retrieved AliDCSValue's
291 if (!IsConnected()) {
292 AliError("Not connected!");
293 return AliDCSClient::fgkBadState;
297 AliDCSMessage requestMessage;
298 requestMessage.CreateRequestMessage(reqType, startTime, endTime,
301 if ((sResult = SendMessage(requestMessage)) < 0) {
302 AliError(Form("Can't send request message! Reason: %s",
303 GetErrorString(sResult)));
308 sResult = ReceiveValueSet(result);
315 //______________________________________________________________________
316 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
317 UInt_t startTime, UInt_t endTime, TMap& result)
319 // get array of DCS values from the DCS server
320 // startTime, endTime: start time and end time of the query
321 // result: map containing the array of alias names. It will be filled with
322 // the values retrieved for each alias
324 if (!IsConnected()) {
325 AliError("Not connected!");
326 return AliDCSClient::fgkBadState;
329 AliDCSMessage multiRequestMessage;
330 multiRequestMessage.CreateMultiRequestMessage(reqType,
336 TObjString* aRequest;
338 // copy request strings to temporary TObjArray because
339 // TMap doesn't guarantee the order of elements!!!
340 while ((aRequest = (TObjString*) iter.Next())) {
341 requests.AddLast(aRequest);
342 if (!multiRequestMessage.AddRequestString(aRequest->String()))
344 return AliDCSClient::fgkInvalidParameter;
349 if ((sResult = SendMessage(multiRequestMessage)) < 0) {
350 AliError(Form("Can't send request message! Reason: %s",
351 GetErrorString(sResult)));
359 TIter reqIter(&requests);
360 while ((aRequest = (TObjString*) reqIter.Next())) {
361 TObjArray* resultSet = new TObjArray();
362 resultSet->SetOwner(1);
364 if ((sResult = ReceiveValueSet(*resultSet)) < 0) {
365 AliError(Form("Can't get values for %s!" ,
366 aRequest->String().Data()));
372 result.Add(aRequest, resultSet);
376 result.DeleteValues();
389 //______________________________________________________________________
390 Int_t AliDCSClient::ReceiveValueSet(TObjArray& result)
392 // receive set of values
396 AliDCSMessage responseMessage;
397 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
398 AliError(Form("Can't receive response message! Reason: %s",
399 GetErrorString(sResult)));
405 if (responseMessage.GetType() == AliDCSMessage::kCount) {
406 valueCount = responseMessage.GetCount();
408 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
409 fServerErrorCode = responseMessage.GetErrorCode();
410 fServerError = responseMessage.GetErrorString();
412 return AliDCSClient::fgkServerError;
415 AliError("Bad message type received!");
416 return AliDCSClient::fgkBadMessage;
419 UInt_t receivedValues = 0;
421 AliDCSValue::Type valueType = AliDCSValue::kInvalid;
423 while (receivedValues < valueCount) {
425 AliDCSMessage message;
427 if ((sResult = ReceiveMessage(message)) < 0) {
428 AliError(Form("Can't receive message! Reason: %s",
429 GetErrorString(sResult)));
433 if (message.GetType() == AliDCSMessage::kResultSet) {
435 if (valueType == AliDCSValue::kInvalid) {
436 valueType = message.GetValueType();
438 if (valueType != message.GetValueType()) {
439 AliError("Unexpected value type!");
440 return AliDCSClient::fgkBadMessage;
444 receivedValues += message.GetValues(result);
446 if (receivedValues > valueCount) {
447 AliError("Message contains more values than expected!");
448 return AliDCSClient::fgkBadMessage;
451 } else if (message.GetType() == AliDCSMessage::kError) {
453 responseMessage.GetErrorCode();
454 fServerError = responseMessage.GetErrorString();
456 return AliDCSClient::fgkServerError;
458 AliError("Bad message type received!");
459 return AliDCSClient::fgkBadMessage;
463 return receivedValues;
466 //______________________________________________________________________
467 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
468 UInt_t endTime, TObjArray& result)
471 // Reads a values from the server which correspond to this
472 // DataPoint (dpName) in time interval (startTime - endTime).
473 // result: Collection of AliDCSValue which contains the read values.
476 // If >= 0 , the number of values read.
477 // if < 0, the error code which has occured during the read.
480 return GetValues(AliDCSMessage::kDPName,
481 dpName, startTime, endTime, result);
484 //______________________________________________________________________
485 Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
486 UInt_t endTime, TObjArray& result)
489 // Reads a values from the server which correspond to this
490 // alias (alias) in time interval (startTime - endTime).
491 // result: Collection of AliDCSValue which contains the read values.
494 // If >= 0 , the number of values read.
495 // if < 0, the error code which has occured during the read.
498 return GetValues(AliDCSMessage::kAlias,
499 alias, startTime, endTime, result);
502 //______________________________________________________________________
503 Int_t AliDCSClient::GetDPValues(UInt_t startTime, UInt_t endTime,
507 // For every key of 'result' (which must be TObjString)
508 // reads a valueSet. The key represents particular DataPoint to be read.
509 // For all DataPoints time interval (startTime - endTime) is used.
510 // After the read, the correspoding value for every key is a
511 // TObjArray - collection of AliDCSValue, or result is an empty map in
515 // If >= 0 , the number of values read.
516 // if < 0, the error code which has occured during the read.
519 return GetValues(AliDCSMessage::kDPName, startTime, endTime, result);
522 //______________________________________________________________________
523 Int_t AliDCSClient::GetAliasValues(UInt_t startTime, UInt_t endTime,
527 // For every key of 'result' (which must be TObjString)
528 // reads a valueSet. The key represents particular Alias to be read.
529 // For all aliases time interval (startTime - endTime) is used.
530 // After the read, the correspoding value for every key is a
531 // TObjArray - collection of AliDCSValue, or result is an empty map in
535 // If >= 0 , the number of values read.
536 // if < 0, the error code which has occured during the read.
539 return GetValues(AliDCSMessage::kAlias, startTime, endTime, result);
542 //______________________________________________________________________
543 Bool_t AliDCSClient::IsConnected()
546 // Returns kTRUE if there is a valid connection to the server.
550 return fSocket->IsValid();
556 //______________________________________________________________________
557 void AliDCSClient::Close()
560 // Close the connection.
568 //______________________________________________________________________
569 const char* AliDCSClient::GetErrorString(Int_t code)
572 // Returns a short string describing the error code.
573 // code: the error code.
578 case AliDCSClient::fgkBadState:
579 return AliDCSClient::fgkBadStateString;
581 case AliDCSClient::fgkInvalidParameter:
582 return AliDCSClient::fgkInvalidParameterString;
584 case AliDCSClient::fgkTimeout:
585 return AliDCSClient::fgkTimeoutString;
587 case AliDCSClient::fgkBadMessage:
588 return AliDCSClient::fgkBadMessageString;
590 case AliDCSClient::fgkCommError:
591 return AliDCSClient::fgkCommErrorString;
593 case AliDCSClient::fgkServerError:
594 return AliDCSClient::fgkServerErrorString;
597 AliErrorGeneral("AliDCSClient::GetErrorString",
598 "Unknown error code!");
599 return "UnknownCode";