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