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.6 2006/10/02 16:38:39 jgrosseo
21 storing of objects that failed to be stored to the grid before
22 interfacing of shuttle status table in daq system
24 Revision 1.5 2006/08/15 10:50:00 jgrosseo
25 effc++ corrections (alberto)
27 Revision 1.4 2006/07/04 14:59:57 jgrosseo
28 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
30 Revision 1.3 2006/06/12 09:11:16 jgrosseo
31 coding conventions (Alberto)
33 Revision 1.2 2006/03/07 07:52:34 hristov
34 New version (B.Yordanov)
36 Revision 1.3 2005/11/17 17:47:34 byordano
37 TList changed to TObjArray
39 Revision 1.2 2005/11/17 14:43:23 byordano
42 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
43 Initial import as subdirectory in AliRoot
45 Revision 1.1.1.1 2005/09/12 22:11:40 byordano
48 Revision 1.3 2005/08/30 10:53:23 byordano
49 some more descriptions added
54 // This class represents the AliDCSClient.
55 // The client used for data retrieval from DCS server.
56 // There are two way for retrieving data from the server.
57 // 1) asking for DP (DataPoint) - usually changed frequently.
58 // 2) asking for Alias (Alias) - alias should be the same through whole
61 // There are two type of read operations:
62 // Asking for single alias/dp or asking for set of aliases/dp
64 // In case of ServerError the coresponding error code and
65 // error string (description) could be got by GetServerErrorCode() and
66 // GetServerErrorString()
69 #include "AliDCSClient.h"
70 #include "AliDCSValue.h"
74 #include <TObjArray.h>
76 #include <TObjString.h>
79 ClassImp(AliDCSClient)
81 const char* AliDCSClient::fgkBadStateString = "BadState";
82 const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
83 const char* AliDCSClient::fgkTimeoutString = "Timeout";
84 const char* AliDCSClient::fgkBadMessageString = "BadMessage";
85 const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
86 const char* AliDCSClient::fgkServerErrorString = "ServerError";
88 //______________________________________________________________________
89 AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
91 fSocket(NULL), fTimeout(timeout), fRetries(retries),
92 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
95 // host: DCS server host
96 // port: DCS server port
97 // timeout: in case of communication error or socket read/write this
98 // timeout will be used before the next try is made.
99 // retries: the number of retries after which the connection is
100 // is considered as invalid and error is returned.
105 while (tries < fRetries) {
106 fSocket = new TSocket(host, port);
107 if (fSocket->IsValid()) {
108 AliDebug(1, Form("Connected to %s:%d", host, port));
109 fSocket->SetOption(kNoBlock, 1);
113 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
118 gSystem->Sleep(fTimeout);
123 //______________________________________________________________________
124 AliDCSClient::AliDCSClient(const AliDCSClient& /*other*/):
125 TObject(), fSocket(NULL), fTimeout(0), fRetries(0),
126 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
129 // copy constructor (not implemented)
133 //______________________________________________________________________
134 AliDCSClient &AliDCSClient::operator=(const AliDCSClient& /*other*/)
136 // assignment operator (not implemented)
141 //______________________________________________________________________
142 AliDCSClient::~AliDCSClient()
152 //______________________________________________________________________
153 Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size)
155 // send buffer containing the message to the DCS server
160 while (sentSize < size && tries < fRetries) {
162 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
165 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
169 } else if (sResult < 0) {
170 AliDebug(1, Form("Communication error <%d>!",
171 fSocket->GetErrorCode()));
172 return AliDCSClient::fgkCommError;
175 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
181 AliDebug(1, Form("Communication error <%d>!",
182 fSocket->GetErrorCode()));
183 return AliDCSClient::fgkCommError;
187 if (tries == fRetries) {
188 return AliDCSClient::fgkTimeout;
194 //______________________________________________________________________
195 Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size)
197 // Receive message from the DCS server and fill buffer
199 Int_t receivedSize = 0;
202 while (receivedSize < size && tries < fRetries) {
204 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
207 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
211 } else if (sResult < 0) {
212 AliDebug(1, Form("Communication error <%d>",
213 fSocket->GetErrorCode()));
214 return AliDCSClient::fgkCommError;
217 sResult = fSocket->RecvRaw(buffer + receivedSize,
218 size - receivedSize, kDontBlock);
221 receivedSize += sResult;
223 AliDebug(1, Form("Communication error <%d>",
224 fSocket->GetErrorCode()));
225 return AliDCSClient::fgkCommError;
229 if (tries == fRetries) {
230 return AliDCSClient::fgkTimeout;
236 //______________________________________________________________________
237 Int_t AliDCSClient::SendMessage(AliDCSMessage& message)
239 // send message to the DCS server
241 message.StoreToBuffer();
243 AliDebug(2, "Sending message.\n");
246 return SendBuffer(message.GetMessage(), message.GetMessageSize());
249 //______________________________________________________________________
250 Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message)
252 // receive message from the DCS server
254 char header[HEADER_SIZE];
258 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
259 AliDebug(1, Form("Can't receive message header! Reason: %s",
260 GetErrorString(sResult)));
264 if (!message.SetRawHeader(header)) {
265 return AliDCSClient::fgkBadMessage;
268 if ((sResult = ReceiveBuffer(message.GetBody(),
269 message.GetBodySize())) < 0) {
271 AliDebug(1, Form("Can't receive message body! Reason: %s",
272 GetErrorString(sResult)));
276 message.LoadFromBuffer();
278 AliDebug(2, "Message received.");
281 return HEADER_SIZE + sResult;
284 //______________________________________________________________________
285 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
286 const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray* result)
288 // get array of DCS values from the DCS server
289 // reqString: alias name
290 // startTime, endTime: start time and end time of the query
291 // result: contains the array of retrieved AliDCSValue's
293 if (!IsConnected()) {
294 AliError("Not connected!");
295 return AliDCSClient::fgkBadState;
299 AliDCSMessage requestMessage;
300 requestMessage.CreateRequestMessage(reqType, startTime, endTime,
303 if ((sResult = SendMessage(requestMessage)) < 0) {
304 AliError(Form("Can't send request message! Reason: %s",
305 GetErrorString(sResult)));
310 sResult = ReceiveValueSet(result);
317 //______________________________________________________________________
318 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
319 UInt_t startTime, UInt_t endTime, TMap& result)
321 // get array of DCS values from the DCS server
322 // startTime, endTime: start time and end time of the query
323 // result: map containing the array of alias names. It will be filled with
324 // the values retrieved for each alias
326 if (!IsConnected()) {
327 AliError("Not connected!");
328 return AliDCSClient::fgkBadState;
331 AliDCSMessage multiRequestMessage;
332 multiRequestMessage.CreateMultiRequestMessage(reqType,
338 TObjString* aRequest;
340 // copy request strings to temporary TObjArray because
341 // TMap doesn't guarantee the order of elements!!!
342 while ((aRequest = (TObjString*) iter.Next())) {
343 requests.AddLast(aRequest);
344 if (!multiRequestMessage.AddRequestString(aRequest->String()))
346 return AliDCSClient::fgkInvalidParameter;
351 if ((sResult = SendMessage(multiRequestMessage)) < 0) {
352 AliError(Form("Can't send request message! Reason: %s",
353 GetErrorString(sResult)));
361 TIter reqIter(&requests);
362 while ((aRequest = (TObjString*) reqIter.Next())) {
363 TObjArray* resultSet = new TObjArray();
364 resultSet->SetOwner(1);
366 if ((sResult = ReceiveValueSet(resultSet)) < 0) {
367 AliError(Form("Can't get values for %s!" ,
368 aRequest->String().Data()));
374 result.Add(aRequest, resultSet);
378 result.DeleteValues();
391 //______________________________________________________________________
392 Int_t AliDCSClient::ReceiveValueSet(TObjArray* result)
394 // receive set of values
398 AliDCSMessage responseMessage;
399 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
400 AliError(Form("Can't receive response message! Reason: %s",
401 GetErrorString(sResult)));
407 if (responseMessage.GetType() == AliDCSMessage::kCount) {
408 valueCount = responseMessage.GetCount();
410 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
411 fServerErrorCode = responseMessage.GetErrorCode();
412 fServerError = responseMessage.GetErrorString();
414 return AliDCSClient::fgkServerError;
417 AliError("Bad message type received!");
418 return AliDCSClient::fgkBadMessage;
421 UInt_t receivedValues = 0;
423 AliDCSValue::Type valueType = AliDCSValue::kInvalid;
425 while (receivedValues < valueCount) {
427 AliDCSMessage message;
429 if ((sResult = ReceiveMessage(message)) < 0) {
430 AliError(Form("Can't receive message! Reason: %s",
431 GetErrorString(sResult)));
435 if (message.GetType() == AliDCSMessage::kResultSet) {
437 if (valueType == AliDCSValue::kInvalid) {
438 valueType = message.GetValueType();
440 if (valueType != message.GetValueType()) {
441 AliError("Unexpected value type!");
442 return AliDCSClient::fgkBadMessage;
446 receivedValues += message.GetValues(result);
448 if (receivedValues > valueCount) {
449 AliError("Message contains more values than expected!");
450 return AliDCSClient::fgkBadMessage;
453 } else if (message.GetType() == AliDCSMessage::kError) {
455 responseMessage.GetErrorCode();
456 fServerError = responseMessage.GetErrorString();
458 return AliDCSClient::fgkServerError;
460 AliError("Bad message type received!");
461 return AliDCSClient::fgkBadMessage;
465 return receivedValues;
468 //______________________________________________________________________
469 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
470 UInt_t endTime, TObjArray* result)
473 // Reads a values from the server which correspond to this
474 // DataPoint (dpName) in time interval (startTime - endTime).
475 // result: Collection of AliDCSValue which contains the read values.
478 // If >= 0 , the number of values read.
479 // if < 0, the error code which has occured during the read.
482 return GetValues(AliDCSMessage::kDPName,
483 dpName, startTime, endTime, result);
486 //______________________________________________________________________
487 Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
488 UInt_t endTime, TObjArray* result)
491 // Reads a values from the server which correspond to this
492 // alias (alias) in time interval (startTime - endTime).
493 // result: Collection of AliDCSValue which contains the read values.
496 // If >= 0 , the number of values read.
497 // if < 0, the error code which has occured during the read.
500 return GetValues(AliDCSMessage::kAlias,
501 alias, startTime, endTime, result);
504 //______________________________________________________________________
505 Int_t AliDCSClient::GetDPValues(UInt_t startTime, UInt_t endTime,
509 // For every key of 'result' (which must be TObjString)
510 // reads a valueSet. The key represents particular DataPoint to be read.
511 // For all DataPoints time interval (startTime - endTime) is used.
512 // After the read, the correspoding value for every key is a
513 // TObjArray - collection of AliDCSValue, or result is an empty map in
517 // If >= 0 , the number of values read.
518 // if < 0, the error code which has occured during the read.
521 return GetValues(AliDCSMessage::kDPName, startTime, endTime, result);
524 //______________________________________________________________________
525 Int_t AliDCSClient::GetAliasValues(UInt_t startTime, UInt_t endTime,
529 // For every key of 'result' (which must be TObjString)
530 // reads a valueSet. The key represents particular Alias to be read.
531 // For all aliases time interval (startTime - endTime) is used.
532 // After the read, the correspoding value for every key is a
533 // TObjArray - collection of AliDCSValue, or result is an empty map in
537 // If >= 0 , the number of values read.
538 // if < 0, the error code which has occured during the read.
541 return GetValues(AliDCSMessage::kAlias, startTime, endTime, result);
544 //______________________________________________________________________
545 Bool_t AliDCSClient::IsConnected()
548 // Returns kTRUE if there is a valid connection to the server.
552 return fSocket->IsValid();
558 //______________________________________________________________________
559 void AliDCSClient::Close()
562 // Close the connection.
570 //______________________________________________________________________
571 const char* AliDCSClient::GetErrorString(Int_t code)
574 // Returns a short string describing the error code.
575 // code: the error code.
580 case AliDCSClient::fgkBadState:
581 return AliDCSClient::fgkBadStateString;
583 case AliDCSClient::fgkInvalidParameter:
584 return AliDCSClient::fgkInvalidParameterString;
586 case AliDCSClient::fgkTimeout:
587 return AliDCSClient::fgkTimeoutString;
589 case AliDCSClient::fgkBadMessage:
590 return AliDCSClient::fgkBadMessageString;
592 case AliDCSClient::fgkCommError:
593 return AliDCSClient::fgkCommErrorString;
595 case AliDCSClient::fgkServerError:
596 return AliDCSClient::fgkServerErrorString;
599 AliErrorGeneral("AliDCSClient::GetErrorString",
600 "Unknown error code!");
601 return "UnknownCode";