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.3 2006/06/12 09:11:16 jgrosseo
19 coding conventions (Alberto)
21 Revision 1.2 2006/03/07 07:52:34 hristov
22 New version (B.Yordanov)
24 Revision 1.3 2005/11/17 17:47:34 byordano
25 TList changed to TObjArray
27 Revision 1.2 2005/11/17 14:43:23 byordano
30 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
31 Initial import as subdirectory in AliRoot
33 Revision 1.1.1.1 2005/09/12 22:11:40 byordano
36 Revision 1.3 2005/08/30 10:53:23 byordano
37 some more descriptions added
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
49 // There are two type of read operations:
50 // Asking for single alias/dp or asking for set of aliases/dp
52 // In case of ServerError the coresponding error code and
53 // error string (description) could be got by GetServerErrorCode() and
54 // GetServerErrorString()
57 #include "AliDCSClient.h"
58 #include "AliDCSValue.h"
62 #include <TObjArray.h>
64 #include <TObjString.h>
67 ClassImp(AliDCSClient)
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;
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";
83 //______________________________________________________________________
84 AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
86 fSocket(NULL), fTimeout(timeout), fRetries(retries),
87 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
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.
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);
108 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
113 gSystem->Sleep(fTimeout);
118 //______________________________________________________________________
119 AliDCSClient::AliDCSClient(const AliDCSClient& /*other*/):
122 // copy constructor (not implemented)
126 //______________________________________________________________________
127 AliDCSClient &AliDCSClient::operator=(const AliDCSClient& /*other*/)
129 // assignment operator (not implemented)
134 //______________________________________________________________________
135 AliDCSClient::~AliDCSClient()
145 //______________________________________________________________________
146 Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size)
148 // send buffer containing the message to the DCS server
153 while (sentSize < size && tries < fRetries) {
155 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
158 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
162 } else if (sResult < 0) {
163 AliDebug(1, Form("Communication error <%d>!",
164 fSocket->GetErrorCode()));
165 return AliDCSClient::fgkCommError;
168 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
174 AliDebug(1, Form("Communication error <%d>!",
175 fSocket->GetErrorCode()));
176 return AliDCSClient::fgkCommError;
180 if (tries == fRetries) {
181 return AliDCSClient::fgkTimeout;
187 //______________________________________________________________________
188 Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size)
190 // Receive message from the DCS server and fill buffer
192 Int_t receivedSize = 0;
195 while (receivedSize < size && tries < fRetries) {
197 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
200 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
204 } else if (sResult < 0) {
205 AliDebug(1, Form("Communication error <%d>",
206 fSocket->GetErrorCode()));
207 return AliDCSClient::fgkCommError;
210 sResult = fSocket->RecvRaw(buffer + receivedSize,
211 size - receivedSize, kDontBlock);
214 receivedSize += sResult;
216 AliDebug(1, Form("Communication error <%d>",
217 fSocket->GetErrorCode()));
218 return AliDCSClient::fgkCommError;
222 if (tries == fRetries) {
223 return AliDCSClient::fgkTimeout;
229 //______________________________________________________________________
230 Int_t AliDCSClient::SendMessage(AliDCSMessage& message)
232 // send message to the DCS server
234 message.StoreToBuffer();
236 AliDebug(2, "Sending message.\n");
239 return SendBuffer(message.GetMessage(), message.GetMessageSize());
242 //______________________________________________________________________
243 Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message)
245 // receive message from the DCS server
247 char header[HEADER_SIZE];
251 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
252 AliDebug(1, Form("Can't receive message header! Reason: %s",
253 GetErrorString(sResult)));
257 if (!message.SetRawHeader(header)) {
258 return AliDCSClient::fgkBadMessage;
261 if ((sResult = ReceiveBuffer(message.GetBody(),
262 message.GetBodySize())) < 0) {
264 AliDebug(1, Form("Can't receive message body! Reason: %s",
265 GetErrorString(sResult)));
269 message.LoadFromBuffer();
271 AliDebug(2, "Message received.");
274 return HEADER_SIZE + sResult;
277 //______________________________________________________________________
278 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
279 const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray& result)
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
286 if (!IsConnected()) {
287 AliError("Not connected!");
288 return AliDCSClient::fgkBadState;
292 AliDCSMessage requestMessage;
293 requestMessage.CreateRequestMessage(reqType, startTime, endTime,
296 if ((sResult = SendMessage(requestMessage)) < 0) {
297 AliError(Form("Can't send request message! Reason: %s",
298 GetErrorString(sResult)));
303 sResult = ReceiveValueSet(result);
310 //______________________________________________________________________
311 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
312 UInt_t startTime, UInt_t endTime, TMap& result)
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
319 if (!IsConnected()) {
320 AliError("Not connected!");
321 return AliDCSClient::fgkBadState;
324 AliDCSMessage multiRequestMessage;
325 multiRequestMessage.CreateMultiRequestMessage(reqType,
331 TObjString* aRequest;
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()))
339 return AliDCSClient::fgkInvalidParameter;
344 if ((sResult = SendMessage(multiRequestMessage)) < 0) {
345 AliError(Form("Can't send request message! Reason: %s",
346 GetErrorString(sResult)));
354 TIter reqIter(&requests);
355 while ((aRequest = (TObjString*) reqIter.Next())) {
356 TObjArray* resultSet = new TObjArray();
357 resultSet->SetOwner(1);
359 if ((sResult = ReceiveValueSet(*resultSet)) < 0) {
360 AliError(Form("Can't get values for %s!" ,
361 aRequest->String().Data()));
367 result.Add(aRequest, resultSet);
371 result.DeleteValues();
384 //______________________________________________________________________
385 Int_t AliDCSClient::ReceiveValueSet(TObjArray& result)
387 // receive set of values
391 AliDCSMessage responseMessage;
392 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
393 AliError(Form("Can't receive response message! Reason: %s",
394 GetErrorString(sResult)));
400 if (responseMessage.GetType() == AliDCSMessage::kCount) {
401 valueCount = responseMessage.GetCount();
403 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
404 fServerErrorCode = responseMessage.GetErrorCode();
405 fServerError = responseMessage.GetErrorString();
407 return AliDCSClient::fgkServerError;
410 AliError("Bad message type received!");
411 return AliDCSClient::fgkBadMessage;
414 UInt_t receivedValues = 0;
416 AliDCSValue::Type valueType = AliDCSValue::kInvalid;
418 while (receivedValues < valueCount) {
420 AliDCSMessage message;
422 if ((sResult = ReceiveMessage(message)) < 0) {
423 AliError(Form("Can't receive message! Reason: %s",
424 GetErrorString(sResult)));
428 if (message.GetType() == AliDCSMessage::kResultSet) {
430 if (valueType == AliDCSValue::kInvalid) {
431 valueType = message.GetValueType();
433 if (valueType != message.GetValueType()) {
434 AliError("Unexpected value type!");
435 return AliDCSClient::fgkBadMessage;
439 receivedValues += message.GetValues(result);
441 if (receivedValues > valueCount) {
442 AliError("Message contains more values than expected!");
443 return AliDCSClient::fgkBadMessage;
446 } else if (message.GetType() == AliDCSMessage::kError) {
448 responseMessage.GetErrorCode();
449 fServerError = responseMessage.GetErrorString();
451 return AliDCSClient::fgkServerError;
453 AliError("Bad message type received!");
454 return AliDCSClient::fgkBadMessage;
458 return receivedValues;
461 //______________________________________________________________________
462 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
463 UInt_t endTime, TObjArray& result)
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.
471 // If >= 0 , the number of values read.
472 // if < 0, the error code which has occured during the read.
475 return GetValues(AliDCSMessage::kDPName,
476 dpName, startTime, endTime, result);
479 //______________________________________________________________________
480 Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
481 UInt_t endTime, TObjArray& result)
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.
489 // If >= 0 , the number of values read.
490 // if < 0, the error code which has occured during the read.
493 return GetValues(AliDCSMessage::kAlias,
494 alias, startTime, endTime, result);
497 //______________________________________________________________________
498 Int_t AliDCSClient::GetDPValues(UInt_t startTime, UInt_t endTime,
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
510 // If >= 0 , the number of values read.
511 // if < 0, the error code which has occured during the read.
514 return GetValues(AliDCSMessage::kDPName, startTime, endTime, result);
517 //______________________________________________________________________
518 Int_t AliDCSClient::GetAliasValues(UInt_t startTime, UInt_t endTime,
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
530 // If >= 0 , the number of values read.
531 // if < 0, the error code which has occured during the read.
534 return GetValues(AliDCSMessage::kAlias, startTime, endTime, result);
537 //______________________________________________________________________
538 Bool_t AliDCSClient::IsConnected()
541 // Returns kTRUE if there is a valid connection to the server.
545 return fSocket->IsValid();
551 //______________________________________________________________________
552 void AliDCSClient::Close()
555 // Close the connection.
563 //______________________________________________________________________
564 const char* AliDCSClient::GetErrorString(Int_t code)
567 // Returns a short string describing the error code.
568 // code: the error code.
573 case AliDCSClient::fgkBadState:
574 return AliDCSClient::fgkBadStateString;
576 case AliDCSClient::fgkInvalidParameter:
577 return AliDCSClient::fgkInvalidParameterString;
579 case AliDCSClient::fgkTimeout:
580 return AliDCSClient::fgkTimeoutString;
582 case AliDCSClient::fgkBadMessage:
583 return AliDCSClient::fgkBadMessageString;
585 case AliDCSClient::fgkCommError:
586 return AliDCSClient::fgkCommErrorString;
588 case AliDCSClient::fgkServerError:
589 return AliDCSClient::fgkServerErrorString;
592 AliErrorGeneral("AliDCSClient::GetErrorString",
593 "Unknown error code!");
594 return "UnknownCode";