Revised versions of getters inherited from AliVParticle
[u/mrichter/AliRoot.git] / SHUTTLE / DCSClient / AliDCSClient.cxx
CommitLineData
73abe331 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/*
17$Log$
bee83158 18Revision 1.2 2007/06/09 13:01:09 jgrosseo
19Switching to retrieval of several DCS DPs at a time (multiDPrequest)
20
a038aa70 21Revision 1.1 2006/11/06 14:22:47 jgrosseo
22major update (Alberto)
23o) reading of run parameters from the logbook
24o) online offline naming conversion
25o) standalone DCSclient package
26
eba76848 27Revision 1.6 2006/10/02 16:38:39 jgrosseo
28update (alberto):
29fixed memory leaks
30storing of objects that failed to be stored to the grid before
31interfacing of shuttle status table in daq system
32
2bb7b766 33Revision 1.5 2006/08/15 10:50:00 jgrosseo
34effc++ corrections (alberto)
35
4f0ab988 36Revision 1.4 2006/07/04 14:59:57 jgrosseo
37revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
38
45a493ce 39Revision 1.3 2006/06/12 09:11:16 jgrosseo
40coding conventions (Alberto)
41
58bc3020 42Revision 1.2 2006/03/07 07:52:34 hristov
43New version (B.Yordanov)
44
d477ad88 45Revision 1.3 2005/11/17 17:47:34 byordano
46TList changed to TObjArray
47
48Revision 1.2 2005/11/17 14:43:23 byordano
49import to local CVS
50
51Revision 1.1.1.1 2005/10/28 07:33:58 hristov
52Initial import as subdirectory in AliRoot
53
73abe331 54Revision 1.1.1.1 2005/09/12 22:11:40 byordano
55SHUTTLE package
56
57Revision 1.3 2005/08/30 10:53:23 byordano
58some more descriptions added
59
60*/
61
62//
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
68// experimnet.
69//
70// There are two type of read operations:
71// Asking for single alias/dp or asking for set of aliases/dp
72//
73// In case of ServerError the coresponding error code and
74// error string (description) could be got by GetServerErrorCode() and
75// GetServerErrorString()
76//
77
78#include "AliDCSClient.h"
73abe331 79#include "AliDCSValue.h"
80#include "AliLog.h"
81
58bc3020 82#include <TSocket.h>
d477ad88 83#include <TObjArray.h>
73abe331 84#include <TMap.h>
85#include <TObjString.h>
86#include <TSystem.h>
87
88ClassImp(AliDCSClient)
89
73abe331 90const char* AliDCSClient::fgkBadStateString = "BadState";
73abe331 91const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
73abe331 92const char* AliDCSClient::fgkTimeoutString = "Timeout";
73abe331 93const char* AliDCSClient::fgkBadMessageString = "BadMessage";
73abe331 94const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
73abe331 95const char* AliDCSClient::fgkServerErrorString = "ServerError";
96
58bc3020 97//______________________________________________________________________
73abe331 98AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
99 Int_t retries):
bee83158 100 fSocket(NULL), fHost(host), fPort(port), fTimeout(timeout), fRetries(retries),
73abe331 101 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
102{
103 //
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.
110 //
73abe331 111}
112
58bc3020 113//______________________________________________________________________
bee83158 114AliDCSClient::~AliDCSClient()
58bc3020 115{
bee83158 116 // destructor
58bc3020 117
bee83158 118 Close();
58bc3020 119}
120
121//______________________________________________________________________
bee83158 122Bool_t AliDCSClient::Connect()
58bc3020 123{
bee83158 124 // connects to the AMANDA server
125
126 Close();
127
128 Int_t tries = 0;
129 while (tries < fRetries)
130 {
131 fSocket = new TSocket(fHost, fPort);
132 if (fSocket->IsValid())
133 {
134 AliDebug(1, Form("Connected to %s:%d", fHost.Data(), fPort));
135 fSocket->SetOption(kNoBlock, 1);
136 return kTRUE;
137 }
58bc3020 138
bee83158 139 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
58bc3020 140
73abe331 141 delete fSocket;
bee83158 142 fSocket = NULL;
143
144 gSystem->Sleep(fTimeout);
145 tries ++;
73abe331 146 }
bee83158 147
148 return kFALSE;
73abe331 149}
150
58bc3020 151//______________________________________________________________________
152Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size)
153{
154// send buffer containing the message to the DCS server
73abe331 155
156 Int_t sentSize = 0;
157 Int_t tries = 0;
158
159 while (sentSize < size && tries < fRetries) {
160
161 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
162
163 if (sResult == 0) {
164 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
165 tries ++;
166 continue;
167
168 } else if (sResult < 0) {
169 AliDebug(1, Form("Communication error <%d>!",
170 fSocket->GetErrorCode()));
171 return AliDCSClient::fgkCommError;
172 }
173
174 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
175 kDontBlock);
176
177 if (sResult > 0) {
178 sentSize += sResult;
179 } else {
180 AliDebug(1, Form("Communication error <%d>!",
181 fSocket->GetErrorCode()));
182 return AliDCSClient::fgkCommError;
183 }
184 }
185
186 if (tries == fRetries) {
187 return AliDCSClient::fgkTimeout;
188 }
189
190 return sentSize;
191}
192
58bc3020 193//______________________________________________________________________
194Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size)
195{
196// Receive message from the DCS server and fill buffer
73abe331 197
198 Int_t receivedSize = 0;
199 Int_t tries = 0;
200
201 while (receivedSize < size && tries < fRetries) {
202
203 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
204
205 if (sResult == 0) {
206 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
207 tries ++;
208 continue;
209
210 } else if (sResult < 0) {
211 AliDebug(1, Form("Communication error <%d>",
212 fSocket->GetErrorCode()));
213 return AliDCSClient::fgkCommError;
214 }
215
216 sResult = fSocket->RecvRaw(buffer + receivedSize,
217 size - receivedSize, kDontBlock);
218
219 if (sResult > 0) {
220 receivedSize += sResult;
221 } else {
222 AliDebug(1, Form("Communication error <%d>",
223 fSocket->GetErrorCode()));
224 return AliDCSClient::fgkCommError;
225 }
226 }
227
228 if (tries == fRetries) {
229 return AliDCSClient::fgkTimeout;
230 }
231
232 return receivedSize;
233}
234
58bc3020 235//______________________________________________________________________
236Int_t AliDCSClient::SendMessage(AliDCSMessage& message)
237{
238// send message to the DCS server
73abe331 239
240 message.StoreToBuffer();
241
242 AliDebug(2, "Sending message.\n");
243 message.Print();
244
245 return SendBuffer(message.GetMessage(), message.GetMessageSize());
246}
247
58bc3020 248//______________________________________________________________________
249Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message)
250{
251// receive message from the DCS server
73abe331 252
253 char header[HEADER_SIZE];
254
255 Int_t sResult;
256
257 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
258 AliDebug(1, Form("Can't receive message header! Reason: %s",
259 GetErrorString(sResult)));
260 return sResult;
261 }
262
263 if (!message.SetRawHeader(header)) {
264 return AliDCSClient::fgkBadMessage;
265 }
266
267 if ((sResult = ReceiveBuffer(message.GetBody(),
268 message.GetBodySize())) < 0) {
269
270 AliDebug(1, Form("Can't receive message body! Reason: %s",
271 GetErrorString(sResult)));
272 return sResult;
273 }
274
275 message.LoadFromBuffer();
276
277 AliDebug(2, "Message received.");
278 message.Print();
279
280 return HEADER_SIZE + sResult;
281}
282
58bc3020 283//______________________________________________________________________
73abe331 284Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
2bb7b766 285 const char* reqString, UInt_t startTime, UInt_t endTime, TObjArray* result)
73abe331 286{
bee83158 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
58bc3020 291
bee83158 292 Connect();
293
73abe331 294 if (!IsConnected()) {
295 AliError("Not connected!");
296 return AliDCSClient::fgkBadState;
297 }
298
bee83158 299 Int_t sResult = -1;
73abe331 300 AliDCSMessage requestMessage;
2bb7b766 301 requestMessage.CreateRequestMessage(reqType, startTime, endTime,
73abe331 302 reqString);
303
304 if ((sResult = SendMessage(requestMessage)) < 0) {
305 AliError(Form("Can't send request message! Reason: %s",
306 GetErrorString(sResult)));
307 Close();
308 return sResult;
2bb7b766 309 }
310
73abe331 311 sResult = ReceiveValueSet(result);
2bb7b766 312
73abe331 313 Close();
314
315 return sResult;
316}
317
58bc3020 318//______________________________________________________________________
a038aa70 319TMap* AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
320 const TSeqCollection* list, UInt_t startTime, UInt_t endTime,
321 Int_t startIndex, Int_t endIndex)
73abe331 322{
a038aa70 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
325 //
326 // Result: map containing the array of alias names. It will be filled with
327 // the values retrieved for each alias
58bc3020 328
bee83158 329 Connect();
330
73abe331 331 if (!IsConnected()) {
332 AliError("Not connected!");
a038aa70 333 return 0;
2bb7b766 334 }
73abe331 335
336 AliDCSMessage multiRequestMessage;
2bb7b766 337 multiRequestMessage.CreateMultiRequestMessage(reqType,
73abe331 338 startTime, endTime);
339
a038aa70 340 if (endIndex < 0 || endIndex > list->GetEntries())
341 endIndex = list->GetEntries();
342
343 for (Int_t i=startIndex; i<endIndex; i++)
344 {
345 TObjString* aRequest = (TObjString*) list->At(i);
73abe331 346 if (!multiRequestMessage.AddRequestString(aRequest->String()))
a038aa70 347 return 0;
73abe331 348 }
a038aa70 349
350 Int_t sResult = 0;
351 if ((sResult = SendMessage(multiRequestMessage)) < 0)
352 {
73abe331 353 AliError(Form("Can't send request message! Reason: %s",
354 GetErrorString(sResult)));
355 Close();
a038aa70 356 return 0;
73abe331 357 }
358
a038aa70 359 TMap* result = new TMap;
360 result->SetOwner(1);
73abe331 361
a038aa70 362 for (Int_t i=startIndex; i<endIndex; i++)
363 {
364 TObjString* aRequest = (TObjString*) list->At(i);
365
d477ad88 366 TObjArray* resultSet = new TObjArray();
73abe331 367 resultSet->SetOwner(1);
368
2bb7b766 369 if ((sResult = ReceiveValueSet(resultSet)) < 0) {
73abe331 370 AliError(Form("Can't get values for %s!" ,
371 aRequest->String().Data()));
372
373 delete resultSet;
a038aa70 374 result->DeleteValues();
375 delete result;
376 return 0;
73abe331 377 }
378
a038aa70 379 result->Add(aRequest, resultSet);
73abe331 380 }
381
382 Close();
383
a038aa70 384 return result;
73abe331 385}
386
58bc3020 387//______________________________________________________________________
2bb7b766 388Int_t AliDCSClient::ReceiveValueSet(TObjArray* result)
58bc3020 389{
390// receive set of values
73abe331 391
392 Int_t sResult;
393
394 AliDCSMessage responseMessage;
395 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
396 AliError(Form("Can't receive response message! Reason: %s",
397 GetErrorString(sResult)));
398 return sResult;
399 }
400
401 UInt_t valueCount;
402
403 if (responseMessage.GetType() == AliDCSMessage::kCount) {
404 valueCount = responseMessage.GetCount();
405
406 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
407 fServerErrorCode = responseMessage.GetErrorCode();
408 fServerError = responseMessage.GetErrorString();
409
410 return AliDCSClient::fgkServerError;
411
412 } else {
413 AliError("Bad message type received!");
414 return AliDCSClient::fgkBadMessage;
415 }
416
417 UInt_t receivedValues = 0;
418
45a493ce 419 AliDCSValue::Type valueType = AliDCSValue::kInvalid;
73abe331 420
421 while (receivedValues < valueCount) {
422
423 AliDCSMessage message;
424
425 if ((sResult = ReceiveMessage(message)) < 0) {
426 AliError(Form("Can't receive message! Reason: %s",
427 GetErrorString(sResult)));
428 return sResult;
429 }
430
431 if (message.GetType() == AliDCSMessage::kResultSet) {
432
45a493ce 433 if (valueType == AliDCSValue::kInvalid) {
434 valueType = message.GetValueType();
73abe331 435 } else {
45a493ce 436 if (valueType != message.GetValueType()) {
73abe331 437 AliError("Unexpected value type!");
438 return AliDCSClient::fgkBadMessage;
439 }
440 }
2bb7b766 441
73abe331 442 receivedValues += message.GetValues(result);
443
444 if (receivedValues > valueCount) {
445 AliError("Message contains more values than expected!");
446 return AliDCSClient::fgkBadMessage;
447 }
448
449 } else if (message.GetType() == AliDCSMessage::kError) {
450 fServerErrorCode =
451 responseMessage.GetErrorCode();
452 fServerError = responseMessage.GetErrorString();
453
454 return AliDCSClient::fgkServerError;
455 } else {
456 AliError("Bad message type received!");
457 return AliDCSClient::fgkBadMessage;
458 }
459 }
460
461 return receivedValues;
462}
463
58bc3020 464//______________________________________________________________________
73abe331 465Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
2bb7b766 466 UInt_t endTime, TObjArray* result)
73abe331 467{
468 //
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.
472 //
473 // Returns:
474 // If >= 0 , the number of values read.
475 // if < 0, the error code which has occured during the read.
476 //
477
478 return GetValues(AliDCSMessage::kDPName,
479 dpName, startTime, endTime, result);
480}
481
58bc3020 482//______________________________________________________________________
73abe331 483Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
2bb7b766 484 UInt_t endTime, TObjArray* result)
73abe331 485{
486 //
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.
490 //
491 // Returns:
492 // If >= 0 , the number of values read.
493 // if < 0, the error code which has occured during the read.
494 //
495
496 return GetValues(AliDCSMessage::kAlias,
497 alias, startTime, endTime, result);
498}
499
58bc3020 500//______________________________________________________________________
a038aa70 501TMap* AliDCSClient::GetDPValues(const TSeqCollection* dpList, UInt_t startTime, UInt_t endTime,
502 Int_t startIndex, Int_t endIndex)
73abe331 503{
504 //
a038aa70 505 // For every entry (fron startIndex to endIndex) in dpList (which must be TObjString)
73abe331 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
d477ad88 509 // TObjArray - collection of AliDCSValue, or result is an empty map in
73abe331 510 // case of error.
511 //
512 // Returns:
a038aa70 513 // TMap of results, 0 in case of failure
73abe331 514 //
515
a038aa70 516 return GetValues(AliDCSMessage::kDPName, dpList, startTime, endTime, startIndex, endIndex);
73abe331 517}
518
58bc3020 519//______________________________________________________________________
a038aa70 520TMap* AliDCSClient::GetAliasValues(const TSeqCollection* aliasList, UInt_t startTime, UInt_t endTime,
521 Int_t startIndex, Int_t endIndex)
73abe331 522{
523 //
a038aa70 524 // For every entry (fron startIndex to endIndex) in dpList (which must be TObjString)
73abe331 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
d477ad88 528 // TObjArray - collection of AliDCSValue, or result is an empty map in
73abe331 529 // case of error.
530 //
531 // Returns:
a038aa70 532 // TMap of results, 0 in case of failure
73abe331 533 //
534
a038aa70 535 return GetValues(AliDCSMessage::kAlias, aliasList, startTime, endTime, startIndex, endIndex);
73abe331 536}
537
58bc3020 538//______________________________________________________________________
539Bool_t AliDCSClient::IsConnected()
540{
73abe331 541 //
542 // Returns kTRUE if there is a valid connection to the server.
543 //
544
545 if (fSocket) {
546 return fSocket->IsValid();
547 }
548
549 return kFALSE;
550}
551
58bc3020 552//______________________________________________________________________
553void AliDCSClient::Close()
554{
73abe331 555 //
556 // Close the connection.
557 //
558
559 if (fSocket) {
560 fSocket->Close();
bee83158 561 delete fSocket;
562 fSocket = 0;
73abe331 563 }
564}
565
58bc3020 566//______________________________________________________________________
567const char* AliDCSClient::GetErrorString(Int_t code)
568{
73abe331 569 //
570 // Returns a short string describing the error code.
571 // code: the error code.
572 //
573
574
575 switch (code) {
576 case AliDCSClient::fgkBadState:
577 return AliDCSClient::fgkBadStateString;
578
579 case AliDCSClient::fgkInvalidParameter:
580 return AliDCSClient::fgkInvalidParameterString;
581
582 case AliDCSClient::fgkTimeout:
583 return AliDCSClient::fgkTimeoutString;
584
585 case AliDCSClient::fgkBadMessage:
586 return AliDCSClient::fgkBadMessageString;
587
588 case AliDCSClient::fgkCommError:
589 return AliDCSClient::fgkCommErrorString;
590
591 case AliDCSClient::fgkServerError:
592 return AliDCSClient::fgkServerErrorString;
593
594 default:
595 AliErrorGeneral("AliDCSClient::GetErrorString",
596 "Unknown error code!");
597 return "UnknownCode";
598 }
599}
600