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 2005/11/17 17:47:34 byordano
19 TList changed to TObjArray
21 Revision 1.2 2005/11/17 14:43:23 byordano
24 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
25 Initial import as subdirectory in AliRoot
27 Revision 1.1.1.1 2005/09/12 22:11:40 byordano
30 Revision 1.3 2005/08/30 10:53:23 byordano
31 some more descriptions added
36 // This class represents the AliDCSClient.
37 // The client used for data retrieval from DCS server.
38 // There are two way for retrieving data from the server.
39 // 1) asking for DP (DataPoint) - usually changed frequently.
40 // 2) asking for Alias (Alias) - alias should be the same through whole
43 // There are two type of read operations:
44 // Asking for single alias/dp or asking for set of aliases/dp
46 // In case of ServerError the coresponding error code and
47 // error string (description) could be got by GetServerErrorCode() and
48 // GetServerErrorString()
51 #include "AliDCSClient.h"
53 #include "AliDCSValue.h"
56 #include <TObjArray.h>
58 #include <TObjString.h>
61 ClassImp(AliDCSClient)
63 const Int_t AliDCSClient::fgkBadState;
65 const Int_t AliDCSClient::fgkInvalidParameter;
67 const Int_t AliDCSClient::fgkTimeout;
69 const Int_t AliDCSClient::fgkBadMessage;
71 const Int_t AliDCSClient::fgkCommError;
73 const Int_t AliDCSClient::fgkServerError;
75 const char* AliDCSClient::fgkBadStateString = "BadState";
77 const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
79 const char* AliDCSClient::fgkTimeoutString = "Timeout";
81 const char* AliDCSClient::fgkBadMessageString = "BadMessage";
83 const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
85 const char* AliDCSClient::fgkServerErrorString = "ServerError";
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 AliDCSClient::~AliDCSClient() {
128 Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size) {
133 while (sentSize < size && tries < fRetries) {
135 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
138 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
142 } else if (sResult < 0) {
143 AliDebug(1, Form("Communication error <%d>!",
144 fSocket->GetErrorCode()));
145 return AliDCSClient::fgkCommError;
148 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
154 AliDebug(1, Form("Communication error <%d>!",
155 fSocket->GetErrorCode()));
156 return AliDCSClient::fgkCommError;
160 if (tries == fRetries) {
161 return AliDCSClient::fgkTimeout;
167 Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size) {
169 Int_t receivedSize = 0;
172 while (receivedSize < size && tries < fRetries) {
174 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
177 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
181 } else if (sResult < 0) {
182 AliDebug(1, Form("Communication error <%d>",
183 fSocket->GetErrorCode()));
184 return AliDCSClient::fgkCommError;
187 sResult = fSocket->RecvRaw(buffer + receivedSize,
188 size - receivedSize, kDontBlock);
191 receivedSize += sResult;
193 AliDebug(1, Form("Communication error <%d>",
194 fSocket->GetErrorCode()));
195 return AliDCSClient::fgkCommError;
199 if (tries == fRetries) {
200 return AliDCSClient::fgkTimeout;
206 Int_t AliDCSClient::SendMessage(AliDCSMessage& message) {
208 message.StoreToBuffer();
210 AliDebug(2, "Sending message.\n");
213 return SendBuffer(message.GetMessage(), message.GetMessageSize());
216 Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message) {
218 char header[HEADER_SIZE];
222 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
223 AliDebug(1, Form("Can't receive message header! Reason: %s",
224 GetErrorString(sResult)));
228 if (!message.SetRawHeader(header)) {
229 return AliDCSClient::fgkBadMessage;
232 if ((sResult = ReceiveBuffer(message.GetBody(),
233 message.GetBodySize())) < 0) {
235 AliDebug(1, Form("Can't receive message body! Reason: %s",
236 GetErrorString(sResult)));
240 message.LoadFromBuffer();
242 AliDebug(2, "Message received.");
245 return HEADER_SIZE + sResult;
248 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
249 const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray& result)
251 if (!IsConnected()) {
252 AliError("Not connected!");
253 return AliDCSClient::fgkBadState;
257 AliDCSMessage requestMessage;
258 requestMessage.CreateRequestMessage(reqType, startTime, endTime,
261 if ((sResult = SendMessage(requestMessage)) < 0) {
262 AliError(Form("Can't send request message! Reason: %s",
263 GetErrorString(sResult)));
268 sResult = ReceiveValueSet(result);
275 Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
276 UInt_t startTime, UInt_t endTime, TMap& result)
278 if (!IsConnected()) {
279 AliError("Not connected!");
280 return AliDCSClient::fgkBadState;
283 AliDCSMessage multiRequestMessage;
284 multiRequestMessage.CreateMultiRequestMessage(reqType,
290 TObjString* aRequest;
292 // copy request strings to temporary TObjArray because
293 // TMap doesn't guarantee the order of elements!!!
294 while ((aRequest = (TObjString*) iter.Next())) {
295 requests.AddLast(aRequest);
296 if (!multiRequestMessage.AddRequestString(aRequest->String()))
298 return AliDCSClient::fgkInvalidParameter;
303 if ((sResult = SendMessage(multiRequestMessage)) < 0) {
304 AliError(Form("Can't send request message! Reason: %s",
305 GetErrorString(sResult)));
313 TIter reqIter(&requests);
314 while ((aRequest = (TObjString*) reqIter.Next())) {
315 TObjArray* resultSet = new TObjArray();
316 resultSet->SetOwner(1);
318 if ((sResult = ReceiveValueSet(*resultSet)) < 0) {
319 AliError(Form("Can't get values for %s!" ,
320 aRequest->String().Data()));
326 result.Add(aRequest, resultSet);
330 result.DeleteValues();
343 Int_t AliDCSClient::ReceiveValueSet(TObjArray& result) {
347 AliDCSMessage responseMessage;
348 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
349 AliError(Form("Can't receive response message! Reason: %s",
350 GetErrorString(sResult)));
356 if (responseMessage.GetType() == AliDCSMessage::kCount) {
357 valueCount = responseMessage.GetCount();
359 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
360 fServerErrorCode = responseMessage.GetErrorCode();
361 fServerError = responseMessage.GetErrorString();
363 return AliDCSClient::fgkServerError;
366 AliError("Bad message type received!");
367 return AliDCSClient::fgkBadMessage;
370 UInt_t receivedValues = 0;
372 AliSimpleValue::Type valueType = AliSimpleValue::kInvalid;
374 while (receivedValues < valueCount) {
376 AliDCSMessage message;
378 if ((sResult = ReceiveMessage(message)) < 0) {
379 AliError(Form("Can't receive message! Reason: %s",
380 GetErrorString(sResult)));
384 if (message.GetType() == AliDCSMessage::kResultSet) {
386 if (valueType == AliSimpleValue::kInvalid) {
387 valueType = message.GetSimpleValueType();
389 if (valueType != message.GetSimpleValueType()) {
390 AliError("Unexpected value type!");
391 return AliDCSClient::fgkBadMessage;
395 receivedValues += message.GetValues(result);
397 if (receivedValues > valueCount) {
398 AliError("Message contains more values than expected!");
399 return AliDCSClient::fgkBadMessage;
402 } else if (message.GetType() == AliDCSMessage::kError) {
404 responseMessage.GetErrorCode();
405 fServerError = responseMessage.GetErrorString();
407 return AliDCSClient::fgkServerError;
409 AliError("Bad message type received!");
410 return AliDCSClient::fgkBadMessage;
414 return receivedValues;
417 Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
418 UInt_t endTime, TObjArray& result)
421 // Reads a values from the server which correspond to this
422 // DataPoint (dpName) in time interval (startTime - endTime).
423 // result: Collection of AliDCSValue which contains the read values.
426 // If >= 0 , the number of values read.
427 // if < 0, the error code which has occured during the read.
430 return GetValues(AliDCSMessage::kDPName,
431 dpName, startTime, endTime, result);
434 Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
435 UInt_t endTime, TObjArray& result)
438 // Reads a values from the server which correspond to this
439 // alias (alias) in time interval (startTime - endTime).
440 // result: Collection of AliDCSValue which contains the read values.
443 // If >= 0 , the number of values read.
444 // if < 0, the error code which has occured during the read.
447 return GetValues(AliDCSMessage::kAlias,
448 alias, startTime, endTime, result);
451 Int_t AliDCSClient::GetDPValues(UInt_t startTime, UInt_t endTime,
455 // For every key of 'result' (which must be TObjString)
456 // reads a valueSet. The key represents particular DataPoint to be read.
457 // For all DataPoints time interval (startTime - endTime) is used.
458 // After the read, the correspoding value for every key is a
459 // TObjArray - collection of AliDCSValue, or result is an empty map in
463 // If >= 0 , the number of values read.
464 // if < 0, the error code which has occured during the read.
467 return GetValues(AliDCSMessage::kDPName, startTime, endTime, result);
470 Int_t AliDCSClient::GetAliasValues(UInt_t startTime, UInt_t endTime,
474 // For every key of 'result' (which must be TObjString)
475 // reads a valueSet. The key represents particular Alias to be read.
476 // For all aliases time interval (startTime - endTime) is used.
477 // After the read, the correspoding value for every key is a
478 // TObjArray - collection of AliDCSValue, or result is an empty map in
482 // If >= 0 , the number of values read.
483 // if < 0, the error code which has occured during the read.
486 return GetValues(AliDCSMessage::kAlias, startTime, endTime, result);
489 Bool_t AliDCSClient::IsConnected() {
491 // Returns kTRUE if there is a valid connection to the server.
495 return fSocket->IsValid();
501 void AliDCSClient::Close() {
503 // Close the connection.
511 const char* AliDCSClient::GetErrorString(Int_t code) {
513 // Returns a short string describing the error code.
514 // code: the error code.
519 case AliDCSClient::fgkBadState:
520 return AliDCSClient::fgkBadStateString;
522 case AliDCSClient::fgkInvalidParameter:
523 return AliDCSClient::fgkInvalidParameterString;
525 case AliDCSClient::fgkTimeout:
526 return AliDCSClient::fgkTimeoutString;
528 case AliDCSClient::fgkBadMessage:
529 return AliDCSClient::fgkBadMessageString;
531 case AliDCSClient::fgkCommError:
532 return AliDCSClient::fgkCommErrorString;
534 case AliDCSClient::fgkServerError:
535 return AliDCSClient::fgkServerErrorString;
538 AliErrorGeneral("AliDCSClient::GetErrorString",
539 "Unknown error code!");
540 return "UnknownCode";