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.5 2006/08/15 10:50:00 jgrosseo
19 effc++ corrections (alberto)
21 Revision 1.4 2006/07/04 14:59:57 jgrosseo
22 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
24 Revision 1.3 2006/06/12 09:11:16 jgrosseo
25 coding conventions (Alberto)
27 Revision 1.2 2006/03/07 07:52:34 hristov
28 New version (B.Yordanov)
30 Revision 1.3 2005/11/17 17:47:34 byordano
31 TList changed to TObjArray
33 Revision 1.2 2005/11/17 14:43:23 byordano
36 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
37 Initial import as subdirectory in AliRoot
39 Revision 1.1.1.1 2005/09/12 22:11:40 byordano
42 Revision 1.3 2005/08/30 10:53:23 byordano
43 some more descriptions added
48 // This class represents the AliDCSClient.
49 // The client used for data retrieval from DCS server.
50 // There are two way for retrieving data from the server.
51 // 1) asking for DP (DataPoint) - usually changed frequently.
52 // 2) asking for Alias (Alias) - alias should be the same through whole
55 // There are two type of read operations:
56 // Asking for single alias/dp or asking for set of aliases/dp
58 // In case of ServerError the coresponding error code and
59 // error string (description) could be got by GetServerErrorCode() and
60 // GetServerErrorString()
63 #include "AliDCSClient.h"
64 #include "AliDCSValue.h"
68 #include <TObjArray.h>
70 #include <TObjString.h>
73 ClassImp(AliDCSClient)
75 const Int_t AliDCSClient::fgkBadState;
76 const Int_t AliDCSClient::fgkInvalidParameter;
77 const Int_t AliDCSClient::fgkTimeout;
78 const Int_t AliDCSClient::fgkBadMessage;
79 const Int_t AliDCSClient::fgkCommError;
80 const Int_t AliDCSClient::fgkServerError;
82 const char* AliDCSClient::fgkBadStateString = "BadState";
83 const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
84 const char* AliDCSClient::fgkTimeoutString = "Timeout";
85 const char* AliDCSClient::fgkBadMessageString = "BadMessage";
86 const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
87 const char* AliDCSClient::fgkServerErrorString = "ServerError";
89 //______________________________________________________________________
90 AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
92 fSocket(NULL), fTimeout(timeout), fRetries(retries),
93 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
96 // host: DCS server host
97 // port: DCS server port
98 // timeout: in case of communication error or socket read/write this
99 // timeout will be used before the next try is made.
100 // retries: the number of retries after which the connection is
101 // is considered as invalid and error is returned.
106 while (tries < fRetries) {
107 fSocket = new TSocket(host, port);
108 if (fSocket->IsValid()) {
109 AliDebug(1, Form("Connected to %s:%d", host, port));
110 fSocket->SetOption(kNoBlock, 1);
114 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
119 gSystem->Sleep(fTimeout);
124 //______________________________________________________________________
125 AliDCSClient::AliDCSClient(const AliDCSClient& /*other*/):
126 TObject(), fSocket(NULL), fTimeout(0), fRetries(0),
127 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
130 // copy constructor (not implemented)
134 //______________________________________________________________________
135 AliDCSClient &AliDCSClient::operator=(const AliDCSClient& /*other*/)
137 // assignment operator (not implemented)
142 //______________________________________________________________________
143 AliDCSClient::~AliDCSClient()
153 //______________________________________________________________________
154 Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size)
156 // send buffer containing the message to the DCS server
161 while (sentSize < size && tries < fRetries) {
163 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
166 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
170 } else if (sResult < 0) {
171 AliDebug(1, Form("Communication error <%d>!",
172 fSocket->GetErrorCode()));
173 return AliDCSClient::fgkCommError;
176 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
182 AliDebug(1, Form("Communication error <%d>!",
183 fSocket->GetErrorCode()));
184 return AliDCSClient::fgkCommError;
188 if (tries == fRetries) {
189 return AliDCSClient::fgkTimeout;
195 //______________________________________________________________________
196 Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size)
198 // Receive message from the DCS server and fill buffer
200 Int_t receivedSize = 0;
203 while (receivedSize < size && tries < fRetries) {
205 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
208 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
212 } else if (sResult < 0) {
213 AliDebug(1, Form("Communication error <%d>",
214 fSocket->GetErrorCode()));
215 return AliDCSClient::fgkCommError;
218 sResult = fSocket->RecvRaw(buffer + receivedSize,
219 size - receivedSize, kDontBlock);
222 receivedSize += sResult;
224 AliDebug(1, Form("Communication error <%d>",
225 fSocket->GetErrorCode()));
226 return AliDCSClient::fgkCommError;
230 if (tries == fRetries) {
231 return AliDCSClient::fgkTimeout;
237 //______________________________________________________________________
238 Int_t AliDCSClient::SendMessage(AliDCSMessage& message)
240 // send message to the DCS server
242 message.StoreToBuffer();
244 AliDebug(2, "Sending message.\n");
247 return SendBuffer(message.GetMessage(), message.GetMessageSize());
250 //______________________________________________________________________
251 Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message)
253 // receive message from the DCS server
255 char header[HEADER_SIZE];
259 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
260 AliDebug(1, Form("Can't receive message header! Reason: %s",
261 GetErrorString(sResult)));
265 if (!message.SetRawHeader(header)) {
266 return AliDCSClient::fgkBadMessage;
269 if ((sResult = ReceiveBuffer(message.GetBody(),
270 message.GetBodySize())) < 0) {
272 AliDebug(1, Form("Can't receive message body! Reason: %s",
273 GetErrorString(sResult)));
277 message.LoadFromBuffer();
279 AliDebug(2, "Message received.");
282 return HEADER_SIZE + sResult;
285 //______________________________________________________________________
286 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
287 const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray* result)
289 // get array of DCS values from the DCS server
290 // reqString: alias name
291 // startTime, endTime: start time and end time of the query
292 // result: contains the array of retrieved AliDCSValue's
294 if (!IsConnected()) {
295 AliError("Not connected!");
296 return AliDCSClient::fgkBadState;
300 AliDCSMessage requestMessage;
301 requestMessage.CreateRequestMessage(reqType, startTime, endTime,
304 if ((sResult = SendMessage(requestMessage)) < 0) {
305 AliError(Form("Can't send request message! Reason: %s",
306 GetErrorString(sResult)));
311 sResult = ReceiveValueSet(result);
318 //______________________________________________________________________
319 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
320 UInt_t startTime, UInt_t endTime, TMap& result)
322 // get array of DCS values from the DCS server
323 // startTime, endTime: start time and end time of the query
324 // result: map containing the array of alias names. It will be filled with
325 // the values retrieved for each alias
327 if (!IsConnected()) {
328 AliError("Not connected!");
329 return AliDCSClient::fgkBadState;
332 AliDCSMessage multiRequestMessage;
333 multiRequestMessage.CreateMultiRequestMessage(reqType,
339 TObjString* aRequest;
341 // copy request strings to temporary TObjArray because
342 // TMap doesn't guarantee the order of elements!!!
343 while ((aRequest = (TObjString*) iter.Next())) {
344 requests.AddLast(aRequest);
345 if (!multiRequestMessage.AddRequestString(aRequest->String()))
347 return AliDCSClient::fgkInvalidParameter;
352 if ((sResult = SendMessage(multiRequestMessage)) < 0) {
353 AliError(Form("Can't send request message! Reason: %s",
354 GetErrorString(sResult)));
362 TIter reqIter(&requests);
363 while ((aRequest = (TObjString*) reqIter.Next())) {
364 TObjArray* resultSet = new TObjArray();
365 resultSet->SetOwner(1);
367 if ((sResult = ReceiveValueSet(resultSet)) < 0) {
368 AliError(Form("Can't get values for %s!" ,
369 aRequest->String().Data()));
375 result.Add(aRequest, resultSet);
379 result.DeleteValues();
392 //______________________________________________________________________
393 Int_t AliDCSClient::ReceiveValueSet(TObjArray* result)
395 // receive set of values
399 AliDCSMessage responseMessage;
400 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
401 AliError(Form("Can't receive response message! Reason: %s",
402 GetErrorString(sResult)));
408 if (responseMessage.GetType() == AliDCSMessage::kCount) {
409 valueCount = responseMessage.GetCount();
411 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
412 fServerErrorCode = responseMessage.GetErrorCode();
413 fServerError = responseMessage.GetErrorString();
415 return AliDCSClient::fgkServerError;
418 AliError("Bad message type received!");
419 return AliDCSClient::fgkBadMessage;
422 UInt_t receivedValues = 0;
424 AliDCSValue::Type valueType = AliDCSValue::kInvalid;
426 while (receivedValues < valueCount) {
428 AliDCSMessage message;
430 if ((sResult = ReceiveMessage(message)) < 0) {
431 AliError(Form("Can't receive message! Reason: %s",
432 GetErrorString(sResult)));
436 if (message.GetType() == AliDCSMessage::kResultSet) {
438 if (valueType == AliDCSValue::kInvalid) {
439 valueType = message.GetValueType();
441 if (valueType != message.GetValueType()) {
442 AliError("Unexpected value type!");
443 return AliDCSClient::fgkBadMessage;
447 receivedValues += message.GetValues(result);
449 if (receivedValues > valueCount) {
450 AliError("Message contains more values than expected!");
451 return AliDCSClient::fgkBadMessage;
454 } else if (message.GetType() == AliDCSMessage::kError) {
456 responseMessage.GetErrorCode();
457 fServerError = responseMessage.GetErrorString();
459 return AliDCSClient::fgkServerError;
461 AliError("Bad message type received!");
462 return AliDCSClient::fgkBadMessage;
466 return receivedValues;
469 //______________________________________________________________________
470 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
471 UInt_t endTime, TObjArray* result)
474 // Reads a values from the server which correspond to this
475 // DataPoint (dpName) in time interval (startTime - endTime).
476 // result: Collection of AliDCSValue which contains the read values.
479 // If >= 0 , the number of values read.
480 // if < 0, the error code which has occured during the read.
483 return GetValues(AliDCSMessage::kDPName,
484 dpName, startTime, endTime, result);
487 //______________________________________________________________________
488 Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
489 UInt_t endTime, TObjArray* result)
492 // Reads a values from the server which correspond to this
493 // alias (alias) in time interval (startTime - endTime).
494 // result: Collection of AliDCSValue which contains the read values.
497 // If >= 0 , the number of values read.
498 // if < 0, the error code which has occured during the read.
501 return GetValues(AliDCSMessage::kAlias,
502 alias, startTime, endTime, result);
505 //______________________________________________________________________
506 Int_t AliDCSClient::GetDPValues(UInt_t startTime, UInt_t endTime,
510 // For every key of 'result' (which must be TObjString)
511 // reads a valueSet. The key represents particular DataPoint to be read.
512 // For all DataPoints time interval (startTime - endTime) is used.
513 // After the read, the correspoding value for every key is a
514 // TObjArray - collection of AliDCSValue, or result is an empty map in
518 // If >= 0 , the number of values read.
519 // if < 0, the error code which has occured during the read.
522 return GetValues(AliDCSMessage::kDPName, startTime, endTime, result);
525 //______________________________________________________________________
526 Int_t AliDCSClient::GetAliasValues(UInt_t startTime, UInt_t endTime,
530 // For every key of 'result' (which must be TObjString)
531 // reads a valueSet. The key represents particular Alias to be read.
532 // For all aliases time interval (startTime - endTime) is used.
533 // After the read, the correspoding value for every key is a
534 // TObjArray - collection of AliDCSValue, or result is an empty map in
538 // If >= 0 , the number of values read.
539 // if < 0, the error code which has occured during the read.
542 return GetValues(AliDCSMessage::kAlias, startTime, endTime, result);
545 //______________________________________________________________________
546 Bool_t AliDCSClient::IsConnected()
549 // Returns kTRUE if there is a valid connection to the server.
553 return fSocket->IsValid();
559 //______________________________________________________________________
560 void AliDCSClient::Close()
563 // Close the connection.
571 //______________________________________________________________________
572 const char* AliDCSClient::GetErrorString(Int_t code)
575 // Returns a short string describing the error code.
576 // code: the error code.
581 case AliDCSClient::fgkBadState:
582 return AliDCSClient::fgkBadStateString;
584 case AliDCSClient::fgkInvalidParameter:
585 return AliDCSClient::fgkInvalidParameterString;
587 case AliDCSClient::fgkTimeout:
588 return AliDCSClient::fgkTimeoutString;
590 case AliDCSClient::fgkBadMessage:
591 return AliDCSClient::fgkBadMessageString;
593 case AliDCSClient::fgkCommError:
594 return AliDCSClient::fgkCommErrorString;
596 case AliDCSClient::fgkServerError:
597 return AliDCSClient::fgkServerErrorString;
600 AliErrorGeneral("AliDCSClient::GetErrorString",
601 "Unknown error code!");
602 return "UnknownCode";