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