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.2 2007/06/09 13:01:09 jgrosseo
19 Switching to retrieval of several DCS DPs at a time (multiDPrequest)
21 Revision 1.1 2006/11/06 14:22:47 jgrosseo
22 major update (Alberto)
23 o) reading of run parameters from the logbook
24 o) online offline naming conversion
25 o) standalone DCSclient package
27 Revision 1.6 2006/10/02 16:38:39 jgrosseo
30 storing of objects that failed to be stored to the grid before
31 interfacing of shuttle status table in daq system
33 Revision 1.5 2006/08/15 10:50:00 jgrosseo
34 effc++ corrections (alberto)
36 Revision 1.4 2006/07/04 14:59:57 jgrosseo
37 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
39 Revision 1.3 2006/06/12 09:11:16 jgrosseo
40 coding conventions (Alberto)
42 Revision 1.2 2006/03/07 07:52:34 hristov
43 New version (B.Yordanov)
45 Revision 1.3 2005/11/17 17:47:34 byordano
46 TList changed to TObjArray
48 Revision 1.2 2005/11/17 14:43:23 byordano
51 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
52 Initial import as subdirectory in AliRoot
54 Revision 1.1.1.1 2005/09/12 22:11:40 byordano
57 Revision 1.3 2005/08/30 10:53:23 byordano
58 some more descriptions added
63 // This class represents the AliDCSClient.
64 // The client used for data retrieval from DCS server.
65 // There are two way for retrieving data from the server.
66 // 1) asking for DP (DataPoint) - usually changed frequently.
67 // 2) asking for Alias (Alias) - alias should be the same through whole
70 // There are two type of read operations:
71 // Asking for single alias/dp or asking for set of aliases/dp
73 // In case of ServerError the coresponding error code and
74 // error string (description) could be got by GetServerErrorCode() and
75 // GetServerErrorString()
78 #include "AliDCSClient.h"
79 #include "AliDCSValue.h"
83 #include <TObjArray.h>
85 #include <TObjString.h>
88 ClassImp(AliDCSClient)
90 const char* AliDCSClient::fgkBadStateString = "BadState";
91 const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
92 const char* AliDCSClient::fgkTimeoutString = "Timeout";
93 const char* AliDCSClient::fgkBadMessageString = "BadMessage";
94 const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
95 const char* AliDCSClient::fgkServerErrorString = "ServerError";
97 //______________________________________________________________________
98 AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
100 fSocket(NULL), fHost(host), fPort(port), fTimeout(timeout), fRetries(retries),
101 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
104 // host: DCS server host
105 // port: DCS server port
106 // timeout: in case of communication error or socket read/write this
107 // timeout will be used before the next try is made.
108 // retries: the number of retries after which the connection is
109 // is considered as invalid and error is returned.
113 //______________________________________________________________________
114 AliDCSClient::~AliDCSClient()
121 //______________________________________________________________________
122 Bool_t AliDCSClient::Connect()
124 // connects to the AMANDA server
129 while (tries < fRetries)
131 fSocket = new TSocket(fHost, fPort);
132 if (fSocket->IsValid())
134 AliDebug(1, Form("Connected to %s:%d", fHost.Data(), fPort));
135 fSocket->SetOption(kNoBlock, 1);
139 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
144 gSystem->Sleep(fTimeout);
151 //______________________________________________________________________
152 Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size)
154 // send buffer containing the message to the DCS server
159 while (sentSize < size && tries < fRetries) {
161 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
164 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
168 } else if (sResult < 0) {
169 AliDebug(1, Form("Communication error <%d>!",
170 fSocket->GetErrorCode()));
171 return AliDCSClient::fgkCommError;
174 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
180 AliDebug(1, Form("Communication error <%d>!",
181 fSocket->GetErrorCode()));
182 return AliDCSClient::fgkCommError;
186 if (tries == fRetries) {
187 return AliDCSClient::fgkTimeout;
193 //______________________________________________________________________
194 Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size)
196 // Receive message from the DCS server and fill buffer
198 Int_t receivedSize = 0;
201 while (receivedSize < size && tries < fRetries) {
203 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
206 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
210 } else if (sResult < 0) {
211 AliDebug(1, Form("Communication error <%d>",
212 fSocket->GetErrorCode()));
213 return AliDCSClient::fgkCommError;
216 sResult = fSocket->RecvRaw(buffer + receivedSize,
217 size - receivedSize, kDontBlock);
220 receivedSize += sResult;
222 AliDebug(1, Form("Communication error <%d>",
223 fSocket->GetErrorCode()));
224 return AliDCSClient::fgkCommError;
228 if (tries == fRetries) {
229 return AliDCSClient::fgkTimeout;
235 //______________________________________________________________________
236 Int_t AliDCSClient::SendMessage(AliDCSMessage& message)
238 // send message to the DCS server
240 message.StoreToBuffer();
242 AliDebug(2, "Sending message.\n");
245 return SendBuffer(message.GetMessage(), message.GetMessageSize());
248 //______________________________________________________________________
249 Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message)
251 // receive message from the DCS server
253 char header[HEADER_SIZE];
257 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
258 AliDebug(1, Form("Can't receive message header! Reason: %s",
259 GetErrorString(sResult)));
263 if (!message.SetRawHeader(header)) {
264 return AliDCSClient::fgkBadMessage;
267 if ((sResult = ReceiveBuffer(message.GetBody(),
268 message.GetBodySize())) < 0) {
270 AliDebug(1, Form("Can't receive message body! Reason: %s",
271 GetErrorString(sResult)));
275 message.LoadFromBuffer();
277 AliDebug(2, "Message received.");
280 return HEADER_SIZE + sResult;
283 //______________________________________________________________________
284 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
285 const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray* result)
287 // get array of DCS values from the DCS server
288 // reqString: alias name
289 // startTime, endTime: start time and end time of the query
290 // 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 TMap* AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
320 const TSeqCollection* list, UInt_t startTime, UInt_t endTime,
321 Int_t startIndex, Int_t endIndex)
323 // get array of DCS values from the DCS server
324 // list, startTime, endTime: list of dp/alias names, start time and end time of the query
326 // Result: map containing the array of alias names. It will be filled with
327 // the values retrieved for each alias
331 if (!IsConnected()) {
332 AliError("Not connected!");
336 AliDCSMessage multiRequestMessage;
337 multiRequestMessage.CreateMultiRequestMessage(reqType,
340 if (endIndex < 0 || endIndex > list->GetEntries())
341 endIndex = list->GetEntries();
343 for (Int_t i=startIndex; i<endIndex; i++)
345 TObjString* aRequest = (TObjString*) list->At(i);
346 if (!multiRequestMessage.AddRequestString(aRequest->String()))
351 if ((sResult = SendMessage(multiRequestMessage)) < 0)
353 AliError(Form("Can't send request message! Reason: %s",
354 GetErrorString(sResult)));
359 TMap* result = new TMap;
362 for (Int_t i=startIndex; i<endIndex; i++)
364 TObjString* aRequest = (TObjString*) list->At(i);
366 TObjArray* resultSet = new TObjArray();
367 resultSet->SetOwner(1);
369 if ((sResult = ReceiveValueSet(resultSet)) < 0) {
370 AliError(Form("Can't get values for %s!" ,
371 aRequest->String().Data()));
374 result->DeleteValues();
379 result->Add(aRequest, resultSet);
387 //______________________________________________________________________
388 Int_t AliDCSClient::ReceiveValueSet(TObjArray* result)
390 // receive set of values
394 AliDCSMessage responseMessage;
395 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
396 AliError(Form("Can't receive response message! Reason: %s",
397 GetErrorString(sResult)));
403 if (responseMessage.GetType() == AliDCSMessage::kCount) {
404 valueCount = responseMessage.GetCount();
406 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
407 fServerErrorCode = responseMessage.GetErrorCode();
408 fServerError = responseMessage.GetErrorString();
410 return AliDCSClient::fgkServerError;
413 AliError("Bad message type received!");
414 return AliDCSClient::fgkBadMessage;
417 UInt_t receivedValues = 0;
419 AliDCSValue::Type valueType = AliDCSValue::kInvalid;
421 while (receivedValues < valueCount) {
423 AliDCSMessage message;
425 if ((sResult = ReceiveMessage(message)) < 0) {
426 AliError(Form("Can't receive message! Reason: %s",
427 GetErrorString(sResult)));
431 if (message.GetType() == AliDCSMessage::kResultSet) {
433 if (valueType == AliDCSValue::kInvalid) {
434 valueType = message.GetValueType();
436 if (valueType != message.GetValueType()) {
437 AliError("Unexpected value type!");
438 return AliDCSClient::fgkBadMessage;
442 receivedValues += message.GetValues(result);
444 if (receivedValues > valueCount) {
445 AliError("Message contains more values than expected!");
446 return AliDCSClient::fgkBadMessage;
449 } else if (message.GetType() == AliDCSMessage::kError) {
451 responseMessage.GetErrorCode();
452 fServerError = responseMessage.GetErrorString();
454 return AliDCSClient::fgkServerError;
456 AliError("Bad message type received!");
457 return AliDCSClient::fgkBadMessage;
461 return receivedValues;
464 //______________________________________________________________________
465 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
466 UInt_t endTime, TObjArray* result)
469 // Reads a values from the server which correspond to this
470 // DataPoint (dpName) in time interval (startTime - endTime).
471 // result: Collection of AliDCSValue which contains the read values.
474 // If >= 0 , the number of values read.
475 // if < 0, the error code which has occured during the read.
478 return GetValues(AliDCSMessage::kDPName,
479 dpName, startTime, endTime, result);
482 //______________________________________________________________________
483 Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
484 UInt_t endTime, TObjArray* result)
487 // Reads a values from the server which correspond to this
488 // alias (alias) in time interval (startTime - endTime).
489 // result: Collection of AliDCSValue which contains the read values.
492 // If >= 0 , the number of values read.
493 // if < 0, the error code which has occured during the read.
496 return GetValues(AliDCSMessage::kAlias,
497 alias, startTime, endTime, result);
500 //______________________________________________________________________
501 TMap* AliDCSClient::GetDPValues(const TSeqCollection* dpList, UInt_t startTime, UInt_t endTime,
502 Int_t startIndex, Int_t endIndex)
505 // For every entry (fron startIndex to endIndex) in dpList (which must be TObjString)
506 // reads a valueSet. The key represents particular DataPoint to be read.
507 // For all DataPoints time interval (startTime - endTime) is used.
508 // After the read, the correspoding value for every key is a
509 // TObjArray - collection of AliDCSValue, or result is an empty map in
513 // TMap of results, 0 in case of failure
516 return GetValues(AliDCSMessage::kDPName, dpList, startTime, endTime, startIndex, endIndex);
519 //______________________________________________________________________
520 TMap* AliDCSClient::GetAliasValues(const TSeqCollection* aliasList, UInt_t startTime, UInt_t endTime,
521 Int_t startIndex, Int_t endIndex)
524 // For every entry (fron startIndex to endIndex) in dpList (which must be TObjString)
525 // reads a valueSet. The key represents particular Alias to be read.
526 // For all aliases time interval (startTime - endTime) is used.
527 // After the read, the correspoding value for every key is a
528 // TObjArray - collection of AliDCSValue, or result is an empty map in
532 // TMap of results, 0 in case of failure
535 return GetValues(AliDCSMessage::kAlias, aliasList, startTime, endTime, startIndex, endIndex);
538 //______________________________________________________________________
539 Bool_t AliDCSClient::IsConnected()
542 // Returns kTRUE if there is a valid connection to the server.
546 return fSocket->IsValid();
552 //______________________________________________________________________
553 void AliDCSClient::Close()
556 // Close the connection.
566 //______________________________________________________________________
567 const char* AliDCSClient::GetErrorString(Int_t code)
570 // Returns a short string describing the error code.
571 // code: the error code.
576 case AliDCSClient::fgkBadState:
577 return AliDCSClient::fgkBadStateString;
579 case AliDCSClient::fgkInvalidParameter:
580 return AliDCSClient::fgkInvalidParameterString;
582 case AliDCSClient::fgkTimeout:
583 return AliDCSClient::fgkTimeoutString;
585 case AliDCSClient::fgkBadMessage:
586 return AliDCSClient::fgkBadMessageString;
588 case AliDCSClient::fgkCommError:
589 return AliDCSClient::fgkCommErrorString;
591 case AliDCSClient::fgkServerError:
592 return AliDCSClient::fgkServerErrorString;
595 AliErrorGeneral("AliDCSClient::GetErrorString",
596 "Unknown error code!");
597 return "UnknownCode";